Nib에서 재사용 가능한 UITableViewCell로드
사용자 지정 UITableViewCell을 설계하고 http://forums.macrumors.com/showthread.php?t=545061 에있는 스레드에 설명 된 기술을 사용하여 잘로드 할 수 있습니다 . 그러나 해당 메서드를 사용하면 더 이상 재사용 식별자로 셀을 초기화 할 수 없습니다. 즉, 호출 할 때마다 각 셀의 완전히 새로운 인스턴스를 만들어야합니다. 누군가 재사용을 위해 특정 셀 유형을 캐시하는 좋은 방법을 알아 냈지만 여전히 Interface Builder에서 디자인 할 수 있습니까?
적절한 메서드 서명을 사용하여 메서드를 구현하기 만하면됩니다.
- (NSString *) reuseIdentifier {
return @"myIdentifier";
}
실제로 Interface Builder에서 셀을 빌드하고 있으므로 여기에 재사용 식별자를 설정하기 만하면됩니다.
또는 Xcode 4를 실행중인 경우 Attributes inspector 탭을 확인하십시오.
(편집 : XIB가 XCode에 의해 생성 된 후에는 빈 UIView가 포함되어 있지만 UITableViewCell이 필요하므로 UIView를 수동으로 제거하고 테이블보기 셀을 삽입해야합니다. 물론 IB는 a에 대한 UITableViewCell 매개 변수를 표시하지 않습니다. UIView.)
이제 iOS 5에는 적절한 UITableView 메서드가 있습니다.
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
이 코드를 원래 어디서 찾았는지 기억이 나지 않지만 지금까지 잘 작동했습니다.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CustomTableCell";
static NSString *CellNib = @"CustomTableCellView";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
// perform additional custom work...
return cell;
}
Interface Builder 설정 예 ...
이 질문에 대한 답을보십시오.
Interface Builder에서 NSCell 서브 클래스를 디자인 할 수 있습니까?
It's not only possible to design a UITableViewCell in IB, it's desirable because otherwise all of the manual wiring and placement of multiple elements is very tedious. Performaance is fine as long as you are careful to make all elements opaque when possible. The reuseID is set in IB for the properties of the UITableViewCell, then you use the matching reuse ID in code when attempting to dequeue.
I also heard from some of the presenters at WWDC last year that you shouldn't make table view cells in IB, but it's a load of bunk.
As of iOS circa 4.0, there are specific instructions in the iOS docs that make this work super-fast:
Scroll down to where it talks about subclassing UITableViewCell.
Here is another option:
NSString * cellId = @"reuseCell";
//...
NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil];
for (id obj in nibObjects)
{
if ([obj isKindOfClass:[CustomTableCell class]])
{
cell = obj;
[cell setValue:cellId forKey:@"reuseIdentifier"];
break;
}
}
I create my custom view cells in a similar manner - except I connect the cell through an IBOutlet.
The [nib objectAt...]
approach is susceptible to changes to positions of items in the array.
The UIViewController
approach is good - just tried it, and it works nice enough.
BUT...
In all cases the initWithStyle
constructor is NOT called, so no default initialisation is done.
I have read various places about using initWithCoder
or awakeFromNib
, but no conclusive evidence that either of these is the right way.
Apart from explicitly calling some initialization method in the cellForRowAtIndexPath
method I haven't found an answer to this yet.
A while back I found a great blog post on this topic at blog.atebits.com, and have since started using Loren Brichter ABTableViewCell class to do all of my UITableViewCells.
You end up with a simple container UIView to put all of your widgets, and scrolling is lightning fast.
Hope this is useful.
This technique also works and doesn't require a funky ivar in your view controller for memory management. Here, the custom table view cell lives in a xib named "CustomCell.xib".
static NSData *sLoadedCustomCell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
if (cell == nil)
{
if (sLoadedCustomCell == nil)
{
// Load the custom table cell xib
// and extract a reference to the cell object returned
// and cache it in a static to avoid reloading the nib again.
for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil])
{
if ([loadedObject isKindOfClass:[UITableViewCell class]])
{
sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain];
break;
}
}
cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell];
}
Louis method worked for me. This is the code I use to create the UITableViewCell from the nib:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];
if (cell == nil)
{
UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil];
cell = (PostCell *)c.view;
[c release];
}
return cell;
}
- (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;
}
The gustavogb solution doesn't work for me, what I tried is :
ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil];
[[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil];
cell = [c.blogTableViewCell retain];
[c release];
It seems to work. The blogTableViewCell is the IBOutlet for the cell and ChainesController is the file's owner.
From the UITableView docs regarding dequeueWithReuseIdentifier
: "A string identifying the cell object to be reused. By default, a reusable cell’s identifier is its class name, but you can change it to any arbitrary value."
Overriding -reuseIdentifer yourself is risky. What happens if you have two subclasses of your cell subclass, and use both of these in a single table view? If they send the reuse identifier call onto super you'll dequeue a cell of the wrong type.............. I think you need to override the reuseIdentifier method, but have it return a supplanted identifier string. Or, if one has not been specified, have it return the class as a string.
For what it's worth, I asked an iPhone engineer about this at one of the iPhone Tech Talks. His answer was, "Yes, it's possible to use IB to create cells. But don't. Please, don't."
I followed Apple's instructions as linked by Ben Mosher (thanks!) but found that Apple omitted an important point. The object they design in IB is just a UITableViewCell, as is the variable they load from it. But if you actually set it up as a custom subclass of UITableViewCell, and write the code files for the subclass, you can write IBOutlet declarations and IBAction methods in the code and wire them up to your custom elements in IB. Then there is no need to use view tags to access these elements and you can create any kind of crazy cell you want. It's Cocoa Touch heaven.
참고 URL : https://stackoverflow.com/questions/413993/loading-a-reusable-uitableviewcell-from-a-nib
'developer tip' 카테고리의 다른 글
Golang에서 http.Get () 요청에 대한 시간 제한을 설정하는 방법은 무엇입니까? (0) | 2020.09.06 |
---|---|
Android에서 둥근 모서리로 사용자 지정 대화 상자를 만드는 방법 (0) | 2020.09.06 |
Spring XML에서 기본 속성 값을 지정하는 방법이 있습니까? (0) | 2020.09.06 |
android-HTC 모바일에서 등급 표시 줄을 클릭 및 터치 할 수 없도록 설정하는 방법 (0) | 2020.09.06 |
Process.Start C #에서 콘솔 창 숨기기 (0) | 2020.09.05 |