好的。有很多问题都涉及到这个问题,但没有一个真正解决我需要的问题。
我需要的很简单,就是获取我在 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 相关的类:XXXBaseTableCell
、XXXBaseTableViewController
、XXXBaseTableCellEntity
。所有 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/