Xib 파일에서 사용자 지정 UITableViewCells를 로드하는 방법은 무엇입니까?
질문은 간단합니다. 정의 로드 UITableViewCell
Xib 파일에서?이렇게 하면 인터페이스 작성기를 사용하여 셀을 설계할 수 있습니다.메모리 관리 문제로 인해 답이 간단하지 않은 것 같습니다.이 스레드는 문제를 언급하고 해결책을 제안하지만 NDA 이전 릴리스이며 코드가 없습니다.여기에 명확한 답을 제시하지 않고 문제를 논의하는 긴 스레드가 있습니다.
제가 사용한 코드는 다음과 같습니다.
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
코드를 하려면 MyCell합니다. MyCell.m/의 입니다.h를 만듭니다.UITableViewCell
가추를 합니다.IBOutlets
필요한 구성 요소에 대해 설명합니다.그런 다음 새 "빈 XIB" 파일을 작성합니다.합니다.UITableViewCell
개체의 식별자를 "MyCellIdentifier"로 설정하고 클래스를 MyCell로 설정하고 구성 요소를 추가합니다.마으로연다니결을 합니다.IBOutlets
각 구성 요소에 대해 설명합니다.IB에서는 파일 소유자를 설정하지 않았습니다.
다른 방법은 파일 소유자 설정을 권장하고 추가 공장 클래스를 통해 Xib가 로드되지 않을 경우 메모리 누수를 경고합니다.계측기/누설 아래에서 위의 내용을 테스트한 결과 메모리 누수가 발생하지 않았습니다.
그렇다면 Xibs에서 세포를 로딩하는 표준적인 방법은 무엇일까요?파일 소유자를 설정합니까?공장이 필요합니까?그렇다면 공장의 코드는 어떻게 됩니까?여러 가지 해결책이 있다면 각각의 장단점을 명확히 하자...
올바른 솔루션은 다음과 같습니다.
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *nib = [UINib nibWithNibName:@"ItemCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:@"ItemCell"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create an instance of ItemCell
PointsItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];
return cell;
}
원저자가 IB 엔지니어에게 추천한 두 가지 방법이 있습니다.
자세한 내용은 실제 게시물을 참조하십시오.저는 2번 방법이 더 간단한 것 같아서 선호합니다.
방법 #1:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Create a temporary UIViewController to instantiate the custom cell.
UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"BDCustomCell" bundle:nil];
// Grab a pointer to the custom cell.
cell = (BDCustomCell *)temporaryController.view;
[[cell retain] autorelease];
// Release the temporary UIViewController.
[temporaryController release];
}
return cell;
}
방법 #2:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}
업데이트(2014):메소드 #2는 여전히 유효하지만 더 이상 이에 대한 설명서가 없습니다.예전에는 공식 문서에 있었지만 지금은 스토리보드를 위해 삭제되었습니다.
Github에 작업 예제를 게시했습니다.
https://github.com/bentford/://github.com/bentford/NibTableCellExample
Swift 4.2용 편집
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tblContacts.register(UINib(nibName: CellNames.ContactsCell, bundle: nil), forCellReuseIdentifier: MyIdentifier)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MyIdentifier, for: indexPath) as! ContactsCell
return cell
}
등록하세요
iOS 7 이후에는 이 프로세스가 다음과 같이 간소화되었습니다(Swift 3.0).
// For registering nib files
tableView.register(UINib(nibName: "MyCell", bundle: Bundle.main), forCellReuseIdentifier: "cell")
// For registering classes
tableView.register(MyCellClass.self, forCellReuseIdentifier: "cell")
(참고) 이것은 또한 셀을 생성함으로써 달성할 수 있습니다.
.xib
또는.stroyboard
파일, 프로토타입 셀.해야 할 셀클래스를 할 수 ▁be▁ofant▁descend▁if▁(▁a).UITableViewCell
물론).
디큐
나중에 (Swift 3.0)을 사용하여 대기열 해제:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "Hello"
return cell
}
차이점은 이 새로운 방법이 세포를 해독할 뿐만 아니라 존재하지 않는 경우에도 생성된다는 것입니다(즉, 당신이 할 필요가 없다는 것을 의미합니다).if (cell == nil)
shenanigans), 그리고 세포는 위의 예와 같이 사용할 준비가 되어 있습니다.
(경고)
tableView.dequeueReusableCell(withIdentifier:for:)
만약 당신이 다른 것을 부른다면, 새로운 행동을 가지고 있습니다.indexPath:
동작을 수 있습니다.nil
예를 , 리고직스하세요화요, 하세주목스.UITableViewCell?
반환 가격
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? MyCellClass
{
// Cell be casted properly
cell.myCustomProperty = true
}
else
{
// Wrong type? Wrong identifier?
}
은 .한 .xib 파일의 유형입니다.UITableViewCell
하위 클래스 또는 다른 레지스터 메서드를 사용합니다.
배열
할 때 셀의 및 보기 등가되어 있고, 을 등록할 때 이미 셀이 것입니다.cellForRowAtIndexPath
간단히 작성하는 방법.
다같이
class MyCell : UITableViewCell
{
// Can be either created manually, or loaded from a nib with prototypes
@IBOutlet weak var labelSomething : UILabel? = nil
}
class MasterViewController: UITableViewController
{
var data = ["Hello", "World", "Kinda", "Cliche", "Though"]
// Register
override func viewDidLoad()
{
super.viewDidLoad()
tableView.register(MyCell.self, forCellReuseIdentifier: "mycell")
// or the nib alternative
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return data.count
}
// Dequeue
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for: indexPath) as! MyCell
cell.labelSomething?.text = data[indexPath.row]
return cell
}
}
물론 이 모든 것은 ObjC에서 동일한 이름으로 사용할 수 있습니다.
Shawn Craver의 대답을 듣고 그것을 조금 치웠습니다.
BBCell.h:
#import <UIKit/UIKit.h>
@interface BBCell : UITableViewCell {
}
+ (BBCell *)cellFromNibNamed:(NSString *)nibName;
@end
BBCell.m:
#import "BBCell.h"
@implementation BBCell
+ (BBCell *)cellFromNibNamed:(NSString *)nibName {
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:NULL];
NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
BBCell *customCell = nil;
NSObject* nibItem = nil;
while ((nibItem = [nibEnumerator nextObject]) != nil) {
if ([nibItem isKindOfClass:[BBCell class]]) {
customCell = (BBCell *)nibItem;
break; // we have a winner
}
}
return customCell;
}
@end
나는 내 모든 UITableViewCell의 BBCell 하위 클래스를 만든 다음 표준을 바꿉니다.
cell = [[[BBDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BBDetailCell"] autorelease];
포함:
cell = (BBDetailCell *)[BBDetailCell cellFromNibNamed:@"BBDetailCell"];
Bentford의 Method #2를 사용했습니다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}
작동하지만 사용자 정의 UITableViewCell .xib 파일에서 파일 소유자에 대한 연결을 주의하십시오.
을 으로써.owner:self
의 신의에loadNibNamed
진술, 당이설니다합을 합니다.UITableViewController
의파서로의 UITableViewCell
.
IB의 헤더 파일로 드래그 앤 드롭하여 작업 및 아웃렛을 설정하면 기본적으로 파일의 소유자로 설정됩니다.
loadNibNamed:owner:options
는 Apple의 .UITableViewController
주인이니까요그러나 여기에 정의된 속성이 없으므로 키 값 코딩을 준수하는 것에 대한 오류가 발생합니다.
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyUITableViewController 0x6a383b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myLabel.'
이벤트가 대신 트리거되면 NSInvalidArgument가 표시됩니다.예외:
-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0'
*** First throw call stack:
(0x1903052 0x15eed0a 0x1904ced 0x1869f00 0x1869ce2 0x1904ec9 0x5885c2 0x58855a 0x62db76 0x62e03f 0x77fa6c 0x24e86d 0x18d7966 0x18d7407 0x183a7c0 0x1839db4 0x1839ccb 0x1f8b879 0x1f8b93e 0x585a9b 0xb904d 0x2c75)
terminate called throwing an exceptionCurrent language: auto; currently objective-c
쉬운 해결 방법은 인터페이스 빌더 연결을 다음 위치로 지정하는 것입니다.UITableViewCell
파일 소유자 대신:
- 파일 소유자를 마우스 오른쪽 단추로 클릭하여 연결 목록을 끌어올립니다.
- Command-Shift-4를 사용하여 화면 캡처(캡처할 영역을 드래그하여 선택)
- 파일 소유자의 연결을 x로 제거합니다.
- 개체 계층에서 UITableCell을 마우스 오른쪽 버튼으로 클릭하고 연결을 다시 추가합니다.
저는 이 답변들 중 어떤 것도 마음에 들지 않기 때문에 글을 올리기로 결정했습니다. 상황은 항상 더 단순할 수 있고 이것이 제가 찾은 가장 간결한 방법입니다.
원하는 대로 Xib in Interface Builder 구축
- 파일 소유자를 NSObject 클래스로 설정
- UITableViewCell을 추가하고 클래스를 MyTableViewCellSubclass로 설정합니다. IB가 충돌하는 경우(이 글에서 Xcode > 4에서 발생), 인터페이스가 아직 배치되어 있다면 Xcode4에서 인터페이스를 수행하는 UIVView를 사용하십시오.
- 이 셀 내부에 하위 뷰를 배치하고 IBOutlet 연결을 .h 또는 .m의 @ 인터페이스에 연결합니다(.m이 내가 선호하는 항목).
UIViewController 또는 UITableViewController 하위 클래스
@implementation ViewController
static NSString *cellIdentifier = @"MyCellIdentier";
- (void) viewDidLoad {
...
[self.tableView registerNib:[UINib nibWithNibName:@"MyTableViewCellSubclass" bundle:nil] forCellReuseIdentifier:cellIdentifier];
}
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTableViewCellSubclass *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
...
return cell;
}
MyTableViewCell 하위 클래스에서
- (id) initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
...
}
return self;
}
인터페이스 작성기를 사용하여 셀을 만드는 경우 인스펙터에서 식별자를 설정했는지 확인합니다.그런 다음 dequeueReusableCellWithIdentifier를 호출할 때도 동일한지 확인합니다.
테이블이 많은 프로젝트에서 실수로 식별자를 설정하는 것을 잊어버렸고, 성능 변화는 밤낮을 가리지 않았습니다.
XIB에서 UITableViewCells를 로드하면 많은 코드가 절약되지만 일반적으로 스크롤 속도가 저하됩니다(실제로는 XIB가 아니라 UIView의 과도한 사용이 원인입니다).
링크 참조를 참조하십시오.
XIB에서 사용자 지정 셀을 만드는 데 사용했던 클래스 방법은 다음과 같습니다.
+ (CustomCell*) createNewCustomCellFromNib {
NSArray* nibContents = [[NSBundle mainBundle]
loadNibNamed:@"CustomCell" owner:self options:NULL];
NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
CustomCell *customCell= nil;
NSObject* nibItem = nil;
while ( (nibItem = [nibEnumerator nextObject]) != nil) {
if ( [nibItem isKindOfClass: [CustomCell class]]) {
customCell = (CustomCell*) nibItem;
if ([customCell.reuseIdentifier isEqualToString: @"CustomCell"]) {
break; // we have a winner
}
else
fuelEntryCell = nil;
}
}
return customCell;
}
그런 다음 XIB에서 클래스 이름을 설정하고 식별자를 재사용합니다.그 후에, 나는 단지 내 뷰 컨트롤러에서 그 메소드를 호출할 수 있습니다.
[[UITableViewCell] alloc] initWithFrame:]
그것은 충분히 빠르며, 제 배송 애플리케이션 중 두 개에서 사용되고 있습니다.전화하는 것보다 더 신뢰할 수 있습니다.[nib objectAtIndex:0]
그리고 적어도 제 생각에는, 스테판 버로의 예보다 더 신뢰할 수 있습니다. 왜냐하면 당신은 올바른 유형의 XIB에서만 보기를 얻을 수 있기 때문입니다.
올바른 해결책은 다음과 같습니다.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
return cell;
}
NIB를 다시 로드하는 데 비용이 많이 듭니다.한 번 로드한 다음 셀이 필요할 때 개체를 인스턴스화하는 것이 좋습니다.참고로 이 방법을 사용하여 UIImageView 등을 닙에 추가할 수 있습니다(애플의 "registerNIB" iOS5는 최상위 개체 하나만 허용 - Bug 10580062 "iOS5 tableView registerNib: 지나치게 제한적").
그래서 제 코드는 아래에 있습니다 - 당신은 NIB에서 한 번 읽으셨습니다(제가 읽었던 것처럼 초기화하거나 viewDidload에서 읽으셨습니다).이때부터 개체에 니브를 인스턴스화한 다음 필요한 개체를 선택합니다.이것은 니브를 반복적으로 장착하는 것보다 훨씬 효율적입니다.
static UINib *cellNib;
+ (void)initialize
{
if(self == [ImageManager class]) {
cellNib = [UINib nibWithNibName:@"ImageManagerCell" bundle:nil];
assert(cellNib);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = @"TheCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil) {
NSArray *topLevelItems = [cellNib instantiateWithOwner:nil options:nil];
NSUInteger idx = [topLevelItems indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
{
UITableViewCell *cell = (UITableViewCell *)obj;
return [cell isKindOfClass:[UITableViewCell class]] && [cell.reuseIdentifier isEqualToString:cellID];
} ];
assert(idx != NSNotFound);
cell = [topLevelItems objectAtIndex:idx];
}
cell.textLabel.text = [NSString stringWithFormat:@"Howdie %d", indexPath.row];
return cell;
}
이것을 확인하세요 - http://eppz.eu/blog/custom-uitableview-cell/ - 컨트롤러 구현에서 한 줄로 끝나는 작은 클래스를 사용하는 정말 편리한 방법:
-(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
return [TCItemCell cellForTableView:tableView
atIndexPath:indexPath
withModelSource:self];
}
올바른 방법은 UITableViewCell 하위 클래스 구현, 헤더 및 XIB를 만드는 것입니다.XIB에서 뷰를 제거하고 테이블 셀을 추가합니다.클래스를 UITableViewCell 하위 클래스의 이름으로 설정합니다.파일 소유자의 경우 UITableViewController 하위 클래스 이름으로 지정합니다.테이블 ViewCell 콘센트를 사용하여 파일 소유자를 셀에 연결합니다.
헤더 파일:
UITableViewCell *_tableViewCell;
@property (assign) IBOutlet UITableViewCell *tableViewCell;
구현 파일:
@synthesize tableViewCell = _tableViewCell;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellIdentifier = @"reusableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:kCellIdentifier owner:self options:nil];
cell = _tableViewCell;
self.tableViewCell = nil;
}
return cell;
}
를 위해 을 입니다.IBOutlet UITableViewCell *cell
사용자의 컨트롤러 클래스에 있습니다.그런 다음 을 호출합니다.NSBundle loadNibNamed
수업 방법, 그것은 그들을 먹여 살릴 것입니다.UITableViewCell
위에 선언된 셀로.
빈 하고 xib를 합니다.UITableViewCell
필요에 따라 설정할 수 있는 IB의 개체입니다. 이 됩니다.IBOutlet
컨트롤러 클래스에 있습니다.
- (UITableViewCell *)tableView:(UITableView *)table
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%@ loading RTEditableCell.xib", [self description] );
static NSString *MyIdentifier = @"editableCellIdentifier";
cell = [table dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"RTEditableCell"
owner:self
options:nil];
}
return cell;
}
NSBundle 추가 사항 loadNibNamed(ADC 로그인)
cocoawithlove.com 기사 컨셉 출처 (전화번호 샘플 앱 받기)
클래스 만들기 사용된클래만스들기정의
AbcViewCell
.UITableViewCell
이 확장 클래스 메서드를 만듭니다.
extension UITableViewCell { class func fromNib<T : UITableViewCell>() -> T { return Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)?[0] as! T } }
사용하세요.
let cell: AbcViewCell = UITableViewCell.fromNib()
셀 을 가져옵니다.#import "CustomCell.h"
그런 다음 아래에 언급된 대로 위임 방법을 변경합니다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
return cell;
}
Swift 4.2 및 Xcode 10에서
3개의 XIB 셀 파일이 있습니다.
ViewDidLoad에서 XIB 파일을 이렇게 등록합니다.
이것이 첫 번째 접근법입니다.
tableView.register(UINib.init(nibName: "XIBCell", bundle: nil), forCellReuseIdentifier: "cell1")
tableView.register(UINib.init(nibName: "XIBCell2", bundle: nil), forCellReuseIdentifier: "cell2")
//tableView.register(UINib.init(nibName: "XIBCell3", bundle: nil), forCellReuseIdentifier: "cell3")
두 번째 접근 방식은 CellForRowAt indexPath에 XIB 파일을 직접 등록합니다.
이것은 내 테이블 뷰 대리자 기능입니다.
//MARK: - Tableview delegates
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//This is first approach
if indexPath.row == 0 {//Load first XIB cell
let placeCell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! XIBCell
return placeCell
//Second approach
} else if indexPath.row == 5 {//Load XIB cell3
var cell = tableView.dequeueReusableCell(withIdentifier:"cell3") as? XIBCell3
if cell == nil{
let arrNib:Array = Bundle.main.loadNibNamed("XIBCell3",owner: self, options: nil)!
cell = arrNib.first as? XIBCell3
}
//ADD action to XIB cell button
cell?.btn.tag = indexPath.row//Add tag to button
cell?.btn.addTarget(self, action: #selector(self.bookbtn1(_:)), for: .touchUpInside);//selector
return cell!
//This is first approach
} else {//Load XIB cell2
let placeCell = tableView.dequeueReusableCell(withIdentifier: "cell2") as! XIBCell2
return placeCell
}
}
이를 위한 방법은 다음과 같습니다. XIB 파일에서 사용자 정의 UITableViewCell 로드... 또 다른 방법
입니다.UITableViewCell
IBOutlet UIView *content
속성 및 코드에서 구성해야 하는 각 사용자 지정 하위 보기에 대한 속성을 입력합니다.그런 다음 SampleCell.xib 파일을 만듭니다.이 nib 파일에서 파일 소유자를 SampleCell로 변경합니다.UIView
필요에 따라 크기를 조정할 수 있습니다.원하는 모든 하위 보기(레이블, 이미지 보기, 버튼 등)를 추가하고 구성합니다.마지막으로, 내용 보기와 하위 보기를 파일 소유자에게 연결합니다.
에 세포를 등록하는 .UITableView
:
protocol Reusable {
static var reuseID: String { get }
}
extension Reusable {
static var reuseID: String {
return String(describing: self)
}
}
extension UITableViewCell: Reusable { }
extension UITableView {
func register<T: UITableViewCell>(cellClass: T.Type = T.self) {
let bundle = Bundle(for: cellClass.self)
if bundle.path(forResource: cellClass.reuseID, ofType: "nib") != nil {
let nib = UINib(nibName: cellClass.reuseID, bundle: bundle)
register(nib, forCellReuseIdentifier: cellClass.reuseID)
} else {
register(cellClass.self, forCellReuseIdentifier: cellClass.reuseID)
}
}
설명:
Reusable
은 이름.protocol 을 하여 셀 를 합니다.다음과 같은 관례를 : 다과준수야합니다해칙을규같은음합▁make.cell ID == class name == nib name
.UITableViewCell
에Reusable
의전UITableView
extension은 nib 또는 클래스를 통해 셀을 등록할 때의 차이를 추상화합니다.
사용 예:
override func viewDidLoad() {
super.viewDidLoad()
let tableView = UITableView()
let cellClasses: [UITableViewCell.Type] = [PostCell.self, ProfileCell.self, CommentCell.self]
cellClasses.forEach(tableView.register)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PostCell.self.reuseID) as? PostCell
...
return cell
}
표준적인 방법이 있는지는 모르겠지만, 제 방법은 다음과 같습니다.
- View 컨트롤러에 대한 xib 생성
- 파일 소유자 클래스를 UIViewController로 설정합니다.
- 보기를 삭제하고 UITableViewCell을 추가합니다.
- UITableViewCell의 클래스를 사용자 정의 클래스로 설정합니다.
- UITableView 셀의 식별자 설정
- 뷰 컨트롤러 뷰의 출구를 UITableViewCell로 설정합니다.
다음 코드를 사용합니다.
MyCustomViewCell *cell = (MyCustomViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
UIViewController* c = [[UIViewController alloc] initWithNibName:CellIdentifier bundle:nil];
cell = (MyCustomViewCell *)c.view;
[c release];
}
예제에서 사용:
[nib objectAtIndex:0]
Apple이 xib의 항목 순서를 변경하면 깨질 수 있습니다.
NSString *CellIdentifier = [NSString stringWithFormat:@"cell %ld %ld",(long)indexPath.row,(long)indexPath.section];
NewsFeedCell *cell = (NewsFeedCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=nil;
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsFeedCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[NewsFeedCell class]])
{
cell = (NewsFeedCell *)currentObject;
break;
}
}
}
return cell;
이 확장에는 Xcode7 베타6이 필요합니다.
extension NSBundle {
enum LoadViewError: ErrorType {
case ExpectedXibToExistButGotNil
case ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
case XibReturnedWrongType
}
func loadView<T>(name: String) throws -> T {
let topLevelObjects: [AnyObject]! = loadNibNamed(name, owner: self, options: nil)
if topLevelObjects == nil {
throw LoadViewError.ExpectedXibToExistButGotNil
}
if topLevelObjects.count != 1 {
throw LoadViewError.ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
}
let firstObject: AnyObject! = topLevelObjects.first
guard let result = firstObject as? T else {
throw LoadViewError.XibReturnedWrongType
}
return result
}
}
사용자 지정 UITableViewCell 1개만 포함된 Xib 파일을 만듭니다.
장전해요.
let cell: BacteriaCell = try NSBundle.mainBundle().loadView("BacteriaCell")
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellReuseIdentifier = "collabCell"
var cell:collabCell! = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? collabCell
if cell == nil {
tableView.register(UINib(nibName: "collabCell", bundle: nil), forCellReuseIdentifier: cellReuseIdentifier)
cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! collabCell!
}
return cell
}
언급URL : https://stackoverflow.com/questions/540345/how-do-you-load-custom-uitableviewcells-from-xib-files
'programing' 카테고리의 다른 글
Xcode에서 기호 파일 처리 (0) | 2023.05.10 |
---|---|
상황에 맞는 메뉴의 메뉴 항목에서 요소 이름 바인딩 (0) | 2023.05.10 |
Node.js에서 사용되지 않는 패키지를 제거하거나 제거하는 npm 명령 (0) | 2023.05.10 |
jQuery 선택기의 와일드카드 (0) | 2023.05.10 |
이상한 AQDefaultDevice 로깅 (0) | 2023.05.10 |