OverView

Android 에서는 ListView는 iOS Legacy UI 에서는 TableView 로 불리고 SwiftUI에서는 List로 불린다. 이 List Widget 혹은 List Object, List Library, List View & Controls 는 다음과 같은 Creation Route 를 가진다.




[기초] TableView 만들기 (Objective-C + Xib)

테이블 뷰는 데이터 소스를 가져와서 한 줄 씩 화면에 뿌려 주는 객체(Object)이다. 또 데이터 소스를 표현하는 줄(Row)이 길어져서 화면을 넘어가면 자동으로 스크롤바가 붙는다. 라이브러리에서 (⌘⇧L 라이브러리 열기 단축키) 테이블 뷰를 Xib에 D&D(Drag & Drop) 한다.

한 화면에 3개의 테이블 뷰를 배치하면 스토리보드(Storyboard, Xib)에서 다음과 같이 표현된다.



원하는 모양으로 화면 구성(뒤에서는 스토리 보드 작성이라고 말한다)을 한다. 

 

화면 구성 후에는 테이블 세팅을 위해 UIViewController<UITableViewDelegate, UITableViewDataSource> 를 상속 받아 구현해 주어야 한다.


Table 의 섹션 개수를 반환한다.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    // Return the number of sections.

    return 1;

}

 

1로 적으면 1개의 섹션이다. 거의 대부분의 테이블은 지속적으로 데이터가 추가되기 때문에 섹션 구분을 하지 않고 보통 1로 두며, 다른 섹션의 경우 별도의 테이블로 만들어 같은 화면에 표시한다. 

 

Table 의 Row 개수를 반환 한다.

- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {

    return [mList count];

}

 

table을 몇 줄로 할 것인지 미리 정한다. 보통 한 파일 내에서 멤버 배열(mList)로 두고 해당 배열의 크기를 row 개수로 정한다.


Table 의 Cell 을 채운다.

하나의 Row를 Cell이라고 한다.

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     

   if (cell == nil) {

       cell = ... 

   }

    

    return cell;

}

 

요약하면, Table View 에서는 Cell 의 개수 먼저 정하고 Cell 을 만드는 것이 중요하다.


코드로 셀을 추가하는 방법

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

 

셀을 코드로 만들어 주면 된다.

 

TIP! : legacy code의 경우, 셀을 코드로 추가한 셀이 복잡한 UI인 경우 refresh 할 때 문제가 된다. 

 

if( cell != nil ) {

       for(int i=0; i<[cell.contentView.subviews count];i++)

           if([cell.contentView.subviews objectAtIndex:i] != nil)

               [[cell.contentView.subviews objectAtIndex:i] removeFromSuperview];

}

 

와 같이 수동으로 삭제한 후 다시 그려주어야 한다.


테이블 셀 클래스 정의

테이블 뷰를 추가 했었던 스토리 보드의 오브젝트 리스트를 보면 Table View 아래 Table View Cell이 있다.

Table View Cell 을 Table View 위로 D&D 한 후. Cell 내부 구성 요소를 만들 수 있다.. 이 후, 셀을 위한 클래스 생성하고 해당 클래스에 셀 내부 구성 요소를 연결 한다.

 

import UIKit

class DragonballCell : UITableViewCell {

    @IBOutlet weak var lbMain: UILabel!
    @IBOutlet weak var lbSub: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

 

만들어진 셀은 테이블 뷰의 cellForRowAt 에서 원하는 소스를 세팅 한다.

let cell: DragonBallCell
cell = (tableView.dequeueReusableCell (withIdentifier: "DragonballCell") as? DragonballCell)!
cell.lbMain.text = "mainText"
cell.lbSub.text = "subText"
return cell



[실전] sqlite DB와 TableView 연동하기

 

onClickCheckingCategory
onClickSerarchingCategory
onClickDownloadSite

 

    NSMutableArray *tCheck = [NSMutableArray arrayWithCapacity:0];
    SqlUtils *db = [[SqlUtils alloc] init];
    [db selectAll_SITE_TPPG_LOC:tCheck];
    
    if([tCheck count] < 1) {
        [GlobalVar alertMsgOKWithTitle:@"mBASS" message:@"현장 정보 자료 받기를 먼저 해 주세요."];
    } else {
        CheckingCategory *v = [[CheckingCategory alloc] initWithNibName:@"CheckingCategory" bundle:[NSBundle mainBundle]];
        self.title = @"";
        [self.navigationController pushViewController:v animated:YES];
        GlobalVar.globalVar.globalcounterofstack4frontview++;
    }

 

 

View를 만든다.


HoldPointView.xib

 


 


 


 


 


 

#ifndef HoldPointView_h
#define HoldPointView_h

@interface HoldPointView : UIViewController {
    
}
@end

#endif /* HoldPointView_h */


 

#import "HoldPointView.h"

@implementation HoldPointView

@end




 





 




@property (weak, nonatomic) IBOutlet UITableView *mTableView;

 

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "HoldPointView" nib but the view outlet was not set.'
terminating with uncaught exception of type NSException



#import "HoldPointView.h"

@implementation HoldPointView

-(void) viewDidLoad {
    [super viewDidLoad];
    self.mTableView.dataSource = self;
    self.mTableView.delegate= self;
    [self.mTableView reloadData];
}

#pragma mark -
#pragma mark === TableView DataSource ===
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
    return 5;
}

#pragma mark -
#pragma mark TableView Delegate
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

 

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *vCell = @"Cell4Default";
    
    UITableViewCell *cell = nil;
    cell = [tableView dequeueReusableCellWithIdentifier:vCell];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:vCell];
        UILabel *vLabel = [[UILabel alloc] initWithFrame:CGRectMake(6, 2, 90, 30)];
        vLabel.textAlignment = UITextAlignmentCenter;
        vLabel.text = @"cell";
        vLabel.textColor = [UIColor blueColor];
        vLabel.backgroundColor = [ UIColor clearColor];
        vLabel.font = [UIFont systemFontOfSize:14];
        [vLabel setAdjustsFontSizeToFitWidth:YES];
        [vLabel setTag:1];
        [cell.contentView addSubview:vLabel];
    }
    return cell;
}

 

@interface HoldPointView : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    
    NSMutableArray *mList;
    
}

 

- (void) selectTable_DDTBT_HPTYPE:(NSMutableArray *)array isAll:(BOOL)isAll {
    NSLog(@"SQLUTILS_selectDong");
    [array removeAllObjects];
    [self checkBackDB];
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        NSString *query = @"select ID_CHK_TYPE \
        ,NM_CHK_TYPE \
        from DDTBT_HPTYPE;";
        NSLog(@"Query = %@", query );
        
        const char *sqlStatement = [query cStringUsingEncoding:NSASCIIStringEncoding];
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                
                DDTBT_HPTYPE *data = [[DDTBT_HPTYPE alloc] init];
                data.ID_CHK_TYPE = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                data.NM_CHK_TYPE = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                
                [array addObject:data];
            }
        }
        sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);
}

 

-(void) viewDidLoad {
    [super viewDidLoad];
    if (nil == mList) mList = [NSMutableArray arrayWithCapacity:0];
    SqlUtils *db = [[SqlUtils alloc] init];
    [db selectTable_DDTBT_HPTYPE:mList isAll:YES];
    self.mTableView.dataSource = self;
    self.mTableView.delegate= self;
    [self.mTableView reloadData];
}

 

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *vCell = @"Cell4Default";
    
    NSUInteger row = [indexPath row];
    
    UITableViewCell *cell = nil;
    cell = [tableView dequeueReusableCellWithIdentifier:vCell];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:vCell];
        UILabel *vLabel = [[UILabel alloc] initWithFrame:CGRectMake(6, 2, 90, 30)];
        vLabel.textAlignment = UITextAlignmentCenter;
        DDTBT_HPTYPE *vHP = [mList objectAtIndex:row];
        vLabel.text = vHP.NM_CHK_TYPE;
        vLabel.textColor = [UIColor blueColor];
        vLabel.backgroundColor = [ UIColor clearColor];
        vLabel.font = [UIFont systemFontOfSize:14];
        [vLabel setAdjustsFontSizeToFitWidth:YES];
        [vLabel setTag:1];
        [cell.contentView addSubview:vLabel];
    }
    return cell;
}

 

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:vCell];
        UIImage *imageUp = [UIImage imageNamed:@"btn_check_o.png"];
        UIImage *imageDn = [UIImage imageNamed:@"btn_check_d.png"];
        UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
        [btn addTarget:self action:@selector(onClickCheck:) forControlEvents:UIControlEventTouchUpInside];
        [btn setImage:imageUp forState:UIControlStateNormal];
        [btn setImage:imageDn forState:UIControlStateSelected];
        [btn setImageEdgeInsets:UIEdgeInsetsMake(4, 6, 4, 2)];
         [btn setTag:0];
        [cell.contentView addSubview:btn];
        
        UILabel *vLabel = [[UILabel alloc] initWithFrame:CGRectMake(6, 2, 90, 30)];
        vLabel.textAlignment = UITextAlignmentCenter;
        DDTBT_HPTYPE *vHP = [mList objectAtIndex:row];
        vLabel.text = vHP.NM_CHK_TYPE;
        vLabel.textColor = [UIColor blueColor];
        vLabel.backgroundColor = [ UIColor clearColor];
        vLabel.font = [UIFont systemFontOfSize:14];
        [vLabel setAdjustsFontSizeToFitWidth:YES];
        [vLabel setTag:1];
        [cell.contentView addSubview:vLabel];
    }

 

 

 

@interface DDTBT_HPTYPE : NSObject {
    NSString    *ID_CHK_TYPE;
    NSString    *NM_CHK_TYPE;
    BOOL        isCheck;
}

@property (nonatomic, strong) NSString    *ID_CHK_TYPE;
@property (nonatomic, strong) NSString    *NM_CHK_TYPE;
@property (nonatomic, assign) BOOL         isCheck;

- (void)clear;

 

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *vCell = @"Cell4Default";
    NSUInteger row = [indexPath row];
    UITableViewCell *cell = nil;
    cell = [tableView dequeueReusableCellWithIdentifier:vCell];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:vCell];
        UIImage *imageUp = [UIImage imageNamed:@"hp_yesorno.png"];
        UIImage *imageDn = [UIImage imageNamed:@"hp_yes.png"];
        UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 15, 22, 22)];
        [btn addTarget:self action:@selector(onClickCheck:) forControlEvents:UIControlEventTouchUpInside];
        [btn setImage:imageUp forState:UIControlStateNormal];
        [btn setImage:imageDn forState:UIControlStateSelected];
        [btn setImageEdgeInsets:UIEdgeInsetsMake(4, 6, 4, 2)];
        [btn setTag:0];
        [cell.contentView addSubview:btn];
        
        UILabel *vLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, 12, 120, 26)];
        vLabel.textAlignment = UITextAlignmentCenter;
        DDTBT_HPTYPE *vHP = [mList objectAtIndex:row];
        vLabel.text = vHP.NM_CHK_TYPE;
        vLabel.textColor = [UIColor blackColor];
        vLabel.backgroundColor = [ UIColor clearColor];
        vLabel.font = [UIFont systemFontOfSize:18];
        [vLabel setAdjustsFontSizeToFitWidth:YES];
        [vLabel setTag:1];
        [cell.contentView addSubview:vLabel];
    } else {
        [((UIButton*)cell.contentView.subviews.firstObject) setSelected:((DDTBT_HPTYPE *)[mList objectAtIndex:row]).isCheck];
    }
    return cell;
}

 

- (void)onClickCheck:(id)sender
{
    // 선택한 로우가 몇번째인지
    UITableViewCell *cell;
    UITableView *tv;
    
    cell = (UITableViewCell*)[[sender superview] superview];
    tv = (UITableView*)cell.superview;
    NSIndexPath *path=[tv indexPathForCell:cell];
    
    NSLog(@"clickCheck4 in BsVrfChkInfoDwIdList");
    
    BOOL chk = NO;
    
    DDTBT_HPTYPE *data2 = nil;
    BOOL ret = NO;
    
    for (int i=0; i<[mList count]; i++) {
        data2 = [mList objectAtIndex:i];
        data2.isCheck = NO;
    }
    [_mTableView reloadData];
    
    DDTBT_HPTYPE *data = [mList objectAtIndex:path.row];
    data.isCheck = YES;
    chk = data.isCheck;
    
    UIButton *btn = sender;
    [btn setSelected:chk];
}


'Objective-C, SQLite3' 카테고리의 다른 글

잘 되던게, 갑자기 안되는 문제 해결.  (0) 2021.05.20
ImageButton  (0) 2021.05.18
UIViewController 중첩  (0) 2021.05.18
SOAP protocol  (0) 2021.05.18
자주 쓰는 팝업 구현방법, 그리고 데이터 넘기기  (0) 2021.05.18

+ Recent posts