기본 프로토콜
<UITableViewDelegate,UITableViewDataSource>
필수메쏘드
* static UITableView의 경우 인스턴스가 미리 생성되어있으므로, 아래 루틴은 필요 없게 된다.
// 전체 열의 갯수(섹션별)
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
// indexPath에 해당하는 UITableViewCell
-(UITableViewCell *)tableView(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// tableview cell 객체를 얻거나 생성해 리턴해 줘야한다.
// 셀식별용 문자열
// static NSString *cellIdentifier=@"cell";
// 재사용가능한 셀 얻는 방식으로 재사용 가능한 셀이 없을 경우 nil을 리턴한다.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"셀식별자"];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"셀식별자"];
}
// cell 데이터 처리
// indexPath를 사용해 실제 데이터의 index를 가져와 UI 컨트롤에 데이터를 설정한다.
// 라벨, 이미지 등등
// 비동기 처리등도 이곳에 추가한다.
NSInteger row = [indexPath row];
cell.label.text = [myList objectAtIndex:row];
.
.
.
return cell;
}
각 셀의 높이값 지정(optional)
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
if( indexPath.row == 0 ) {
return 100;
}
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
별도의 xib 셀 생성하기
UITableViewCell을 상속받은 커스텀셀 클래스 생성.
xib를 생성해 table view cell 추가 후 커스텀셀 클래스 연결.
속성에서 identifier 설정한다.
인터페이스 빌더에서 생성하지 않으면 코드상에서 셀 생성한뒤 identifier를 넣어주어야 한다.
identifier가 정의되지 않으면 dequeue 시에 nil값이 항상 리턴되어, 계속 셀을 만들게 된다.
nib파일 등록
dequeueReusableCellWithIdentifier: forIndexPath: 를 사용하기 위해서는 nib와 identifier가 등록되어야 한다.
UITableViewController 에서 뷰 생성 시점(viewDidLoad 등) 에 nib에 대한 identifier를 정의한다.
[tableView registerNib:[UINib nibWithNibName:@"nib이름" bundle:nil] forCellWithReuseIdentifier:@"셀식별자"];
UITableViewController에서 프로토콜 구현
-(UITableViewCell *)tableView(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// indexPath를 사용한 셀 얻기 : 이방식은 항상 유효한 셀을 리턴하게 된다.
// 자동으로 nib로 셀을 생성해 주기 때문에 nib 파일이 셀식별자와 함께 등록되어 있어야 한다.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"셀식별자"
forIndexPath:indexPath];
// cell 데이터 처리
// 라벨, 이미지 등등
// 비동기 처리등도 이곳에 추가한다.
.
.
.
셀 데이터 처리
이미지등 데이터를 네트워크를 통해 읽어오는 경우 비동기 처리를 하게되는데,
이경우 설정하기 전에 테이블뷰의 현재 indexPath가 사용가능한지 파악해야 한다.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]
이미지 비동기 처리 예)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSURL *url = [NSURL URLWithString:(@"http://url/image.png")];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData: data];
dispatch_async(dispatch_get_main_queue(), ^{
CustomCell *cell = (CustomCell*)[tableView cellForRowAtIndexPath:indexPath];
if( cell != nil ) {
cell.imageView.image = image;
}
});
});
셀의 사이즈 및 레이아웃 관련 사항만 다시그리기
사이즈 변경등으로 셀의 내부 컨텐츠는 건드리지 않고, 셀을 다시 그린다.
내부에 뷰들이 포함될 경우 reload 를 하면 깜박임이 발생하는데, 이경우는 자연스럽게 셀의 모양만 조정된다.
[self.tableView beginUpdates];
[self.tableView endUpdates];
SubView에 맞게 동적으로 늘어나는 Cell
-(void)viewDidLoad에 테이블뷰의 셀 높이의 기본값과 자동계산됨을 설정한다.
self.tableView.estimatedRowHeight = 50;
self.tableView.rowHeight = UITableViewAutomaticDimension;
셀 높이를 반환하는 메쏘드에도 동일한 값을 리턴하도록 한다.
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
return UITableViewAutomaticDimension;
}
동적으로 맞출 View는 -(CGSize)intrinsicContentSize 메쏘드를 제공해야 한다.
UILabel, UIButton, UIImageView 등은 현재 데이터에 따라 intrinsic size을 갱신하고, 위 메쏘드를 통해 사이즈 정보를 반환한다. 커스텀뷰도 이런 컨트롤과 같이 동작하도록 위 메쏘드에서 높이를 계산해 리턴해 주면 된다.
제약조건에 width , height 와 같은 고정된 값이 있는 정적인 구조라면 상하좌우 제약만 추가해주면 자동으로 사이즈가 계산된다.
단 인터페이스 빌더가 셀 크기와 맞지 않는다고 에러를 낼 수 있으니 bottom 의 경우 >= 0 과 같이 잡아주면 인터페이스 빌더에서는 에러를 없애고 런타임시에도 정상 적용된다.
인터페이스 빌더로 디자인 시에 높이나 너비를 확정할 수 없다면, 해당 커스텀 뷰를 셀의 Content View에 넣을때 constraint를 top, leading, bottom, trailing 잡아주고, intrinsicContentSize 를 제공해 줘야 한다.
자동으로 맞추는 높이를 다시 수동으로 임의 조정하는 경우(셀 숨기기 처럼 셀 높이를 0으로 만드는 등) 셀의 프레임 사이즈가 변경되어 기존 제약 조건들과 충돌이 일어나고, 에러 로그가 출력된다.
이경우 bottom 에 연결된 제약조건의 우선순위를 낮춰 주면 해결된다.
내부 크기 변환 등 처리 후 셀내부의 변화가 일어나 크기가 변화 했으니 다시 그리라고 알린다.
[self invalidateIntrinsicContentSize];
[self.tableView beginUpdates];
[self.tableView endUpdates];
* 이것저것
테이블뷰가 보여질때 상단에 마진이 생기는 경우가 있다.
스토리보드에서 뷰컨트롤러의 속성에서 Adjust scroll view insets 을 체크해제하면 된다.
UICollectionView
테이블과 거의 같은데, cell 이외에 supplementary 라는 뷰를 포함할 수 있다.
UICollectionViewLayout 을 통해 스크롤 방향이나 배치를 조정할 수 있다.
UICollection Reusable View 는 헤더나 푸터
UICollection View Cell 은 각 아이템을 나타낸다.
IB에서 Collection View 추가 하고, 내부에 Collection View Cell 추가 한다.
Collection View Cell 의 reusable 을 위해 identifier를 정의
프로토콜
<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
셀얻기
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath*) indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"셀식별자"
forIndexPath:indexPath];
// cell에 데이터 설정
return cell;
}
데이터추가/삭제
데이터 배열에 데이터 추가한뒤 해당 데이터의 indexPath를 얻어서 넣어준다.
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[_dataList[0] count]-1 inSection:0];
[self.collectionView insertItemsAtIndexPaths:@[indexPath]];
삭제시에는 삭제할 NSArray 를 전달해 주면 된다.
[self.collectionView deleteItemsAtIndexPaths:selectedList];
'프로그래밍 > iOS,macOS' 카테고리의 다른 글
오토레이아웃 이것저것 / Constraint / UITextView (0) | 2016.10.25 |
---|---|
커스텀객체와 인터페이스빌더 (0) | 2016.10.23 |
스토리보드 / XIB (0) | 2016.10.22 |
싱글톤 (0) | 2016.10.19 |
코어 데이터 정리 (0) | 2016.10.18 |
슬라이드메뉴 (0) | 2016.10.16 |
파일 가져오기 (0) | 2016.10.16 |
뷰 에니메이션 (0) | 2016.10.13 |
비동기 처리 ( GCD , NSOperation ) (0) | 2016.10.13 |
[objective-c] 블록구문 (0) | 2016.10.13 |