ios - 在动态 UITableView 原型(prototype)中访问行高

标签 ios swift uitableview

好的。有很多问题都涉及到这个问题,但没有一个真正解决我需要的问题。

我需要的很简单,就是获取我在 IB 中为动态(非静态)表格单元格原型(prototype)的“自定义行高”设置的值。

如果表格设置了静态原型(prototype),那么它会被自动接受。但是,当使用动态原型(prototype)时,该值将被忽略以支持表格的主 rowHeight 值。

我希望能够访问这个值,所以我可以在 tableView(_:heightForRowAt:) 方法中返回它。我可以手动执行此操作,方法是使用内部高度表并与原型(prototype)匹配,但这很麻烦而且很笨拙,并且要求原型(prototype)始终出现在特定行中。

tableView(_:heightForRowAt:) 被调用时,我可以合成 reuseID,但我想避免在适当的时间之前加载 viewcell (tableView(_ :cellForRowAt:)).

有什么好的方法可以访问它吗?我在 Apple 文档中没有看到任何关于访问原型(prototype)的文献。

最佳答案

编辑:好的,我知道你的问题是什么。在 iOS 开发中,我们使用 UITableCell 的不同子类来处理这样的任务。像这样:

+ (CGFloat)layoutHeightWithEntity:(id)entity {
    CGFloat layoutHeight = 0;
    // use data to calculate layout height dynamically if needed
    // id data = [entity data];
    // layoutHeight = layoutHeight + [data ...];

    // or use a static layout height if the height of this kind of cells do not change
    layoutHeight = 100;

    return layoutHeight;
}

在您的 View Controller 中,您需要像这样为 TableView 准备数据源:

NSMutableArray *dataList = [NSMutableArray new];

NSMutableArray *firstSection = [NSMutableArray new];
[firstSection addObject:[XXXTableEntity entityWithReuseCellID:@"nameCell" data:someData cellClass:[XXXNameCell class]];
[dataList addObject:firstSection];

NSMutableArray *secondSection = [NSMutableArray new];
[firstSection addObject:[XXXTableEntity entityWithReuseCellID:@"pickerCell" data:someData cellClass:[XXXPickerCell class]];
[dataList addObject:secondSection];

[self setDataList:dataList];

您的 CustomTableEntity 可能如下所示:

+ (instancetype)entityWithEntityID:(NSString *)entityID
                       cellReUseID:(NSString *)cellReUseID
                         cellClass:(Class<XXXBaseTableCellLayout>)cellClass
                        dataEntity:(id)dataEntity
                precalculateHeight:(BOOL)precalculateHeight {

    XXXBaseTableCellEntity *entity = [self new];

    [entity setEntityID:entityID];
    [entity setReuseCellID:cellReUseID];
    [entity setDataEntity:dataEntity];

    [entity setCellClass:cellClass];

    if (precalculateHeight) {
        [entity setLayoutHeight:[cellClass layoutHeightWithEntity:dataEntity]];
    }

    return entity;
}

- (CGFloat)layoutHeight {
    if (_layoutHeight > 0) {

        return _layoutHeight;
    }

    _layoutHeight = [[self cellClass] layoutHeightWithEntity:[self dataEntity]];

    return _layoutHeight;
}

然后在您的 UITableViewDataSource 方法中:

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

    return self.dataList.count;
}

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

    return [self.dataList[section] count];
}

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

    return [[[[self dataList] objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]] layoutHeight];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    XXXTableEntity *entity = [[[self dataList] objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];

    XXXBaseTableCell *cell = [tableView dequeueReusableCellWithIdentifier:[entity reuseCellID] forIndexPath:indexPath];
    [cell configureWithEntity:entity];

    return cell;
}

上面的代码基本上来 self 为我的公司编写的一个框架,但你应该明白了。该框架有 3 个与 TableView 相关的类:XXXBaseTableCellXXXBaseTableViewControllerXXXBaseTableCellEntity。所有 View Controller 都包含 TableView 子类 XXXBaseTableViewController,所有表单元格子类 XXXBaseTableCell,所有表实体子类 XXXBaseTableCellEntity


请问你为什么要这样做?我认为您在使用 TableView 时遇到了一些问题。如果您能解释为什么要这样做,也许我可以帮助您,使您根本不需要这样做。

您无法在标准方法中访问原型(prototype)单元格的高度。但实际上,如果你真的想这样做,你可以访问 Storyboard文件中的任何数据。方法如下:

Storyboard是一个 XML 文件。您在 IB 中编辑 Storyboard文件时所做的一切都编码在 XML 文件中。您可以通过自己解析 XML 文件来访问您需要的任何信息。您可以读取 Storyboard文件中的 XML 数据并将其提供给 XML 解析器以获取 DOM 数据。然后你可以查询 DOM 来获取数据。这是包含 TableView Controller 的测试 Storyboard 的 XML View :

    <!--Table View Controller-->
    <scene sceneID="hbL-mT-mfb">
        <objects>
            <tableViewController id="XNl-aA-YKn" customClass="TableViewController" sceneMemberID="viewController">
                <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="lX1-Ry-xNl">
                    <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                    <prototypes>
                        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" rowHeight="100" id="4rn-ee-JoI">
                            <rect key="frame" x="0.0" y="28" width="375" height="100"/>
                            <autoresizingMask key="autoresizingMask"/>
                            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="4rn-ee-JoI" id="bdN-kI-rps">
                                <rect key="frame" x="0.0" y="0.0" width="375" height="99"/>
                                <autoresizingMask key="autoresizingMask"/>
                            </tableViewCellContentView>
                        </tableViewCell>
                    </prototypes>
                    <connections>
                        <outlet property="dataSource" destination="XNl-aA-YKn" id="GlZ-SO-7gG"/>
                        <outlet property="delegate" destination="XNl-aA-YKn" id="gqq-QI-tZD"/>
                    </connections>
                </tableView>
            </tableViewController>
            <placeholder placeholderIdentifier="IBFirstResponder" id="RCX-w1-742" userLabel="First Responder" sceneMemberID="firstResponder"/>
        </objects>
        <point key="canvasLocation" x="118" y="798"/>
    </scene>

请不要这样做...

关于ios - 在动态 UITableView 原型(prototype)中访问行高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42160619/

相关文章:

ios - Xamarin for iPhone 6s 中没有可用的 750x1334 启动图像选项吗?

ios - 当我的 UIViewController 在我的 Swift 应用程序中显示给用户时,如何检查它是否被查看?

ios - 取消 UISwitch 的自动触发值改变事件

iphone - 如果我的 iTunes 应用程序名称有空格,如何检查我的应用程序 URL 是否有 iTunes?

ios - iPad 周围的黑框 Build

swift - 'requestReview()' 在 iOS 14.0 中被弃用

ios - 使用分页符编辑 NSString

ios - UITableview 部分?

Swift (IOS) 更新异步函数中的参数

ios - Swift - 在条件下执行 performSegue