IT story

스토리 보드의 사용자 정의 셀 행 높이 설정이 응답하지 않습니다

hot-time 2020. 4. 29. 08:11
반응형

스토리 보드의 사용자 정의 셀 행 높이 설정이 응답하지 않습니다


테이블 뷰에서 셀 중 하나의 셀 높이를 조정하려고합니다. 해당 셀의 "크기 검사기"내의 "행 높이"설정에서 크기를 조정하고 있습니다. iPhone에서 앱을 실행할 때 셀의 기본 크기는 테이블보기의 "행 크기"에서 설정됩니다.

테이블 뷰의 "행 크기"를 변경하면 모든 셀의 크기가 변경됩니다. 하나의 셀에 대해서만 사용자 정의 크기를 원하므로 그렇게하고 싶지 않습니다. 문제에 대한 프로그래밍 솔루션이있는 많은 게시물을 보았지만 가능하다면 스토리 보드를 통해 게시하는 것을 선호합니다.


동적 세포, rowHeightjQuery과의 세트는 항상 개별 셀 'rowHeight에 우선합니다.

그러나 정적 셀에서는 rowHeight개별 셀에 설정되어 UITableView를 재정의 할 수 있습니다.

버그인지 확실하지 않으면 Apple이 의도적으로이 작업을 수행하고있을 수 있습니까?


UITableViewController를 사용하는 경우이 메소드를 구현하십시오.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

행의 기능에서 높이를 선택할 수 있습니다. 예를 들어

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
       return 100;
    } 
    else {
       return 60;
    }
}

이 예에서 첫 번째 행 높이는 100 픽셀이고 다른 행은 60 픽셀입니다.

나는 이것이 당신을 도울 수 있기를 바랍니다.


동적 셀의 경우 rowHeighton으로 설정하면 UITableView항상 개별 셀보다 우선합니다 rowHeight.

이 동작은 버그입니다. 두 곳에서 UI를 관리해야 할 때마다 오류가 발생하기 쉽습니다. 예를 들어 스토리 보드에서 셀 크기를 변경하는 경우 셀 크기도 변경해야 heightForRowAtIndexPath:합니다. Apple이 버그를 수정할 때까지 현재 가장 좋은 해결 방법은 재정의하는 heightForRowAtIndexPath:것이지만 스토리 보드의 실제 프로토 타입 셀을 사용하여 마법의 숫자 대신 높이를 결정하십시오 . 예를 들면 다음과 같습니다.

- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    /* In this example, there is a different cell for
       the top, middle and bottom rows of the tableView.
       Each type of cell has a different height.
       self.model contains the data for the tableview 
    */
    static NSString *CellIdentifier;
    if (indexPath.row == 0) 
        CellIdentifier = @"CellTop";
    else if (indexPath.row + 1 == [self.model count] )
        CellIdentifier = @"CellBottom";
    else
        CellIdentifier = @"CellMiddle";

    UITableViewCell *cell = 
              [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    return cell.bounds.size.height;
}

그러면 프로토 타입 셀 높이에 대한 모든 변경 사항이 런타임에 자동으로 선택되며 UI를 스토리 보드와 같은 한 곳에서만 관리하면됩니다.


프로토 타입 셀을 사용하는 스토리 보드에서 작동하도록 다양한 답변 / 의견 힌트에 코드를 작성했습니다.

이 코드는 :

  • 스토리 보드의 명백한 장소 이외의 다른 곳에 셀 높이를 설정할 필요가 없습니다.
  • 성능상의 이유로 높이를 캐시
  • 공통 함수를 사용하여 중복 된 논리를 피하기 위해 인덱스 경로의 셀 식별자를 가져옵니다.

Answerbot, Brennan 및 lensovet에게 감사합니다.

- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = nil;

    switch (indexPath.section)
    {
        case 0:
            cellIdentifier = @"ArtworkCell";
            break;
         <... and so on ...>
    }

    return cellIdentifier;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
    static NSMutableDictionary *heightCache;
    if (!heightCache)
        heightCache = [[NSMutableDictionary alloc] init];
    NSNumber *cachedHeight = heightCache[cellIdentifier];
    if (cachedHeight)
        return cachedHeight.floatValue;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    CGFloat height = cell.bounds.size.height;
    heightCache[cellIdentifier] = @(height);
    return height;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    <... configure cell as usual...>

실제로 행 높이로 변경 해야하는 두 곳이 있습니다. 먼저 셀을 변경 한 다음 테이블보기를 선택하고 크기 검사기를 확인하십시오.


나는 그것이 버그라고 생각한다.

유틸리티 관리자가 아닌 스토리 보드에서 직접 마우스 드래그하여 높이를 조정하십시오.

이 방법 으로이 문제를 해결했습니다.


swift를 사용하는 경우 다음과 같이 사용하십시오. 스토리 보드를 사용하여 행 높이를 선택하지 마십시오. 프로그래밍 방식으로 테이블 행 높이를 다음과 같이 설정하십시오.

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if indexPath.row == 0 || indexPath.row == 1{
        let cell = self.tableView.dequeueReusableCellWithIdentifier("section1", forIndexPath: indexPath) as! Section1TableViewCell
        self.tableView.rowHeight = 150
        cell.label1.text = "hiiiiii"
        cell.label2.text = "Huiiilllllll"
        return cell

    } else {

        let cell = self.tableView.dequeueReusableCellWithIdentifier("section2", forIndexPath: indexPath) as! Section2TableViewCell
        self.tableView.rowHeight = 60
        cell.label3.text = "llll"
        return cell
    }

}

스토리 보드에서 UITableviewCell (UITableviewController-정적 셀)의 높이를 다음 줄의 도움을 받아 얻을 수 있습니다.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
   CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath];

    return height;
}

Open the storyboard in the XML view and try to edit the rowHeight attribute of the wanted element.

It worked for me when I tried to set custom rowHeight for my prototyped row. It's not working via inspector, but via XML it works.


You can use prototype cells with a custom height, and then invoke cellForRowAtIndexPath: and return its frame.height.:.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self tableView:tableView
                    cellForRowAtIndexPath:indexPath];
    return cell.frame.size.height;
}

If you want to set a static row height, you can do something like this:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 120;
}

I have recently been wrestling with this. My issue was the solutions posted above using the heightForRowAtIndexPath: method would work for iOS 7.1 in the Simulator but then have completely screwed up results by simply switching to iOS 8.1.

I began reading more about self-sizing cells (introduced in iOS 8, read here). It was apparent that the use of UITableViewAutomaticDimension would help in iOS 8. I tried using that technique and deleted the use of heightForRowAtIndexPath: and voila, it was working perfect in iOS 8 now. But then iOS 7 wasn't. What was I to do? I needed heightForRowAtIndexPath: for iOS 7 and not for iOS 8.

Here is my solution (trimmed up for brevity's sake) which borrow's from the answer @JosephH posted above:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.estimatedRowHeight = 50.;
    self.tableView.rowHeight = UITableViewAutomaticDimension;

    // ...
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
        return UITableViewAutomaticDimension;

    } else {
        NSString *cellIdentifier = [self reuseIdentifierForCellAtIndexPath:indexPath];
        static NSMutableDictionary *heightCache;
        if (!heightCache)
            heightCache = [[NSMutableDictionary alloc] init];
        NSNumber *cachedHeight = heightCache[cellIdentifier];
        if (cachedHeight)
            return cachedHeight.floatValue;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    CGFloat height = cell.bounds.size.height;
    heightCache[cellIdentifier] = @(height);
    return height;
    }
}

- (NSString *)reuseIdentifierForCellAtIndexPath:(NSIndexPath *)indexPath {
    NSString * reuseIdentifier;
    switch (indexPath.row) {
        case 0:
            reuseIdentifier = EventTitleCellIdentifier;
            break;
        case 2:
            reuseIdentifier = EventDateTimeCellIdentifier;
            break;
        case 4:
            reuseIdentifier = EventContactsCellIdentifier;
            break;
        case 6:
            reuseIdentifier = EventLocationCellIdentifier;
            break;
        case 8:
            reuseIdentifier = NotesCellIdentifier;
            break;
        default:
            reuseIdentifier = SeparatorCellIdentifier;
            break;
    }

    return reuseIdentifier;
}

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0") is actually from a set of macro definitions I am using which I found somewhere (very helpful). They are defined as:

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

For dynamic cells, rowHeight set on the UITableView always overrides the individual cells' rowHeight. Just calculate the dynamic height if the content inside the row.


The same problem occurred when working on XCode 9 using Swift 4.

Add AutoLayout for the UI elements inside the Cell and custom cell row height will work accordingly as specified.


The only real solution I could find is this

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = ...; // Instantiate with a "common" method you'll use again in cellForRowAtIndexPath:
    return cell.frame.size.height;
}

This works and allows not to have an horrible switch/if duplicating the logic already in the StoryBoard. Not sure about performance but I guess when arriving in cellForRow: the cell being already initalized it's as fast. Of course there are probably collateral damages here, but it looks like it works fine for me here.

I also posted this here: https://devforums.apple.com/message/772464

EDIT: Ortwin Gentz reminded me that heightForRowAtIndexPath: will be called for all cells of the TableView, not only the visible ones. Sounds logical since iOS needs to know the total height to be able to show the right scrollbars. It means it's probably fine on small TableViews (like 20 Cells) but forget about it on a 1000 Cell TableView.

Also, the previous trick with XML: Same as first comment for me. The correct value was already there.


Added as a comment, but posting as an answer for visibility:

There seems to also be an issue if you initially setup a table view as "static cells" and then change it to "dynamic prototypes." I had an issue where even the delegate method for heightForRowAtIndexPath was being ignored. I first resolved it by directly editing the storyboard XML, then finally just rebuilt the storyboard scene from scratch, using dynamic prototypes from the start.


Given that I did not find any solution to this problem through Interface Builder, I decided to post a programmatic solution to the problem in Swift using two dynamic cells, even though the initial question asked for a solution through Interface Builder. Regardless I think it could be helpful for the Stack Overflow community:

    import UIKit

    enum SignInUpMenuTableViewControllerCellIdentifier: String {
       case BigButtonCell = "BigButtonCell"
       case LabelCell = "LabelCell"
    }

    class SignInUpMenuTableViewController: UITableViewController {
            let heightCache = [SignInUpMenuTableViewControllerCellIdentifier.BigButtonCell : CGFloat(50),
                              SignInUpMenuTableViewControllerCellIdentifier.LabelCell : CGFloat(115)]

    private func cellIdentifierForIndexPath(indexPath: NSIndexPath) -> SignInUpMenuTableViewControllerCellIdentifier {
        if indexPath.row == 2 {
            return SignInUpMenuTableViewControllerCellIdentifier.LabelCell
        } else {
            return SignInUpMenuTableViewControllerCellIdentifier.BigButtonCell
        }
    }

   override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
       return self.heightCache[self.cellIdentifierForIndexPath(indexPath)]!
   }

   ...

  }

One other thing you can do is to go to your Document Outline, select the table view that your prototype cell is nested. Then on the Size Inspector, change your table view Row Height to your desired value and uncheck the Automatic box.

참고URL : https://stackoverflow.com/questions/8615862/custom-cell-row-height-setting-in-storyboard-is-not-responding

반응형