별도의 delegate / dataSource를 사용할 때 UITableView 문제
일반적인 설명:
작동하는 것으로 시작하기 위해 UITableView
Interface Builder를 사용하여 Xcode 생성 뷰에 배치되었습니다. 보기의 파일 소유자는 Xcode 생성 하위 클래스로 설정됩니다 UIViewController
. 이 서브 클래스에 나는의 구현 작업 추가 numberOfSectionsInTableView: tableView:numberOfRowsInSection:
및 tableView:cellForRowAtIndexPath:
테이블보기의를 dataSource
하고 delegate
인터페이스 빌더의 파일 소유자를 통해이 클래스에 연결되어 있습니다.
위의 구성은 문제없이 작동합니다. 이 문제는이 테이블 뷰 dataSource
와 delegate
구현을 별도의 클래스 로 옮기고 싶을 때 발생합니다. 테이블 뷰 외에 다른 컨트롤이 뷰에 있고 테이블 뷰 관련 코드를 다른 클래스로 옮기고 싶기 때문입니다. 자신의 수업. 이를 위해 다음을 시도합니다.
UITableViewController
Xcode에서 의 새 하위 클래스 만들기- 의 알려진 좋은 구현을 이동
numberOfSectionsInTableView:
,tableView:numberOfRowsInSection:
그리고tableView:cellForRowAtIndexPath:
새로운 서브 클래스 - InterfaceBuilder
UITableViewController
에서 기존 XIB 의 최상위 레벨로를 드래그하고 이에 대해 자동으로 생성 된UIView
/UITableView
를 삭제UITableViewController
한 다음UITableViewController
의 클래스를 새 하위 클래스와 일치하도록 설정합니다. - 이전에 작업 제거
UITableView
의 기존 s의dataSource
와delegate
연결을하고 새에 연결UITableViewController
완료되면 작업중인 UITableView
. 나는 겉보기에 무작위로 발생할 수있는 세 가지 결과 중 하나를 얻게됩니다.
UITableView
로드 할 때tableView:cellForRowAtIndexPath:
인식하지 못하는 개체에 전송 중임 을 나타내는 런타임 오류가 발생 합니다.- 때
UITableView
로드 오류없이 디버거로 프로젝트 나누기 - 오류
UITableView
는 없지만 나타나지 않습니다.
일부 디버깅과이 문제를 재현하기 위해 기본 프로젝트를 만든 경우 일반적으로 위의 세 번째 옵션이 표시됩니다 (오류는 없지만 테이블보기는 표시되지 않음). 좀 NSLog 전화를 추가하고 있지만 것을 발견 numberOfSectionsInTableView:
하고는 numberOfRowsInSection:
모두가 호출지고, cellForRowAtIndexPath:
아니다. 나는 정말 간단한 것을 놓치고 있다고 확신하고, 내가 가진 것보다 더 많은 경험을 가진 누군가에게 대답이 분명 할 수 있기를 바라고 있었다. 이것이 쉬운 대답이 아니라면 일부 코드 나 샘플 프로젝트로 업데이트 해 드리겠습니다. 시간 내 줘서 고마워!
재현 단계를 완료하십시오.
- Xcode에서 새로운 iPhone OS, View-Based Application을 만들고 호출하십시오.
TableTest
TableTestViewController.xib
Interface Builder에서 열고UITableView
제공된 뷰 화면 으로을 끕니다 .UITableView
의dataSource
및delegate
-outlet을 이미TableTestViewController
-class를 나타내는 파일의 소유자에 연결하십시오 . 변경 사항 저장- Xcode로 돌아가서 다음 코드를 추가하십시오.
TableTestViewController.m:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Returning num sections");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"Returning num rows");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Trying to return cell");
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.text = @"Hello";
NSLog(@"Returning cell");
return cell;
}
Build and Go, 그러면 단어
Hello
가UITableView
이제이
UITableView
논리를 별도의 클래스 로 이동 하려면 먼저 Xcode에서 새 파일을 만들고UITableViewController
하위 클래스를 선택하고 클래스를 호출합니다.TableTestTableViewController
- 위의 코드 조각을에서 제거
TableTestViewController.m
하고에 배치TableTestTableViewController.m
하여이 세 가지 메서드의 기본 구현을 우리의 것으로 바꿉니다. - 동일한 파일 내의 Interface Builder로 돌아가서 메인 IB 창으로
TableTestViewController.xib
드래그하고 자동으로 제공된UITableViewController
새UITableView
객체를 삭제 합니다. - 이 새의 클래스를 설정
UITableViewController
하는TableTestTableViewController
- 이전에 작동하던 기존 바인딩에서
dataSource
및delegate
바인딩을 제거하고UITableView
동일한 두 바인딩을 새로TableTestTableViewController
만든 바인딩에 다시 연결합니다 . - 변경 사항을 저장하고 Build and Go를 수행하고 내가 얻은 결과를 얻는 경우
UITableView
더 이상 제대로 작동하지 않습니다.
솔루션 : iPhone 개발자 포럼 의 추가 문제 해결 및 지원을 통해 솔루션을 문서화했습니다! UIViewController
프로젝트 의 주요 하위 클래스에는 UITableViewController
인스턴스를 가리키는 콘센트가 필요 합니다. 이를 수행하려면 기본보기의 헤더 ( TableTestViewController.h
)에 다음을 추가하면됩니다 .
#import "TableTestTableViewController.h"
과
IBOutlet TableTestTableViewController *myTableViewController;
Then, in Interface Builder, connect the new outlet from File's Owner to TableTestTableViewController
in the main IB window. No changes are necessary in the UI part of the XIB. Simply having this outlet in place, even though no user code directly uses it, resolves the problem completely. Thanks to those who've helped and credit goes to BaldEagle on the iPhone Developer Forums for finding the solution.
I followed your steps, recreated the project and ran into the same problem. Basically you are almost there. There are 2 things missing (once fixed it works):
You need to connect the
tableView
of theTableTestTableViewController
to theUITableView
you have on the screen. As I said before because it is notIBOutlet
you can override thetableView
property and make it andIBOutlet
:@interface TableTestTableViewController : UITableViewController { UITableView *tableView; } @property (nonatomic, retain) IBOutlet UITableView *tableView;
Next thing is to add a reference to the
TableTestTableViewController
and retain it in theTableTestViewController
. Otherwise yourTableTestTableViewController
may be released (after loading the nib with nothing hanging on to it.) and that is why you are seeing the erratic results, crashes or nothing showing. To do that add:@interface TableTestViewController : UIViewController { TableTestTableViewController *tableViewController; } @property (nonatomic, retain) IBOutlet TableTestTableViewController *tableViewController;
and connect that in the Interface Builder to the
TableTestTableViewController
instance.
With the above this worked fine on my machine.
Also I think it would be good to state the motivation behind all this (instead of just using the UITableViewController
with its own UITableView
). In my case it was to use other views that just the UITableView
on the same screenful of content. So I can add other UILabels
or UIImages
under UIView
and show the UITableView
under them or above them.
I just spent many hours pulling my hair out trying to figure out why a UITableView
wouldn't show up when when I had it embedded in a separate nib instead of in the main nib. I finally found your discussion above and realized that it was because my UITableViewController
wasn't being retained! Apparently the delegate and datasource properties of UITableView
are not marked "retain" and so my nib was loading but the controller was getting tossed... And due to the wonders of objective-c I got no error messages at all from this... I still don't understand why it didn't crash. I know that I've seen "message sent to released xxx" before... why wasn't it giving me one of those?!?
I think most developers would assume that structure that they build in an interface builder would be held in some larger context (the Nib) and not subject to release. I guess I know why they do this.. so that the iPhone can drop and reload parts of the nib on low memory. But man, that was hard to figure out.
Can someone tell me where I should have read about that behavior in the docs?
Also - about hooking up the view. First, if you drag one in from the UI builder you'll see that they hook up the view property (which is an IBOutlet
) to the table view. It's not necessary to expose the tableView
, that seems to get set internally. In fact it doesn't even seem to be necessary to set the view unless you want viewDidLoad
notification. I've just broken the view connection between my uitableview
and uitableviewcontroller
(only delegate and datasource set) and it's apparently working fine.
Yes for some reason (please chime in if anybody knows why...) tableView
property of the UITableViewController
is not exposed as an IBOutlet
even though it is a public property. So when you use Interface Builder, you can't see that property to connect to your other UITableView
. So in your subclass, you can create a tableView
property marked as an IBOutlet
and connect that.
This all seems hacky and a workaround to me, but it seems to be the only way to separate a UITableViewController's
UITableView
and put it somewhere else in UI hierarchy. I ran into the same issue when I tried to design view where there are things other than the UITableView
and that was the way I solved it... Is this the right approach???
I was able to make this work. I built a really nice dashboard with 4 TableViews and a webview with video. The key is having the separate tableView controllers and the IBOutlets to the other tableview controllers defined in the view controller. In UIB you just need to connect the other tableview controllers to the file owner of the view controller. Then connect the tables to the corresponding view controllers for the datasource and delegate.
ReferenceURL : https://stackoverflow.com/questions/254354/uitableview-issue-when-using-separate-delegate-datasource
'programing' 카테고리의 다른 글
log4j 파일에 대한 로그 파일 분석기가 있습니까? (0) | 2021.01.16 |
---|---|
코드 커버리지 도구는 어떻게 작동합니까? (0) | 2021.01.16 |
ConfigureAwait (false)가 기본 옵션이 아닌 이유는 무엇입니까? (0) | 2021.01.16 |
오프라인 / 온라인 데이터 동기화 설계 (Javascript) (0) | 2021.01.16 |
인수가없는 생성자가있는 객체를 std :: map에 배치하는 방법은 무엇입니까? (0) | 2021.01.15 |