Mat*_*ves 53 uitableview uiscrollview ios autolayout nslayoutconstraint
目前,我正在使用一个UITableView
包含在其中的其他视图UIScrollView
.我希望UITableView
它的高度与其内容高度相同.
更复杂的是,我还插入/删除行以提供手风琴效果,这样当用户点击一行时,它将显示该行的更多细节.
我已完成插入/删除,但目前它没有更新UIScrollView,这是它的超级视图,以便UIScrollView
重新计算内容大小,并且正确显示UITableView
其中的其他视图UIScrollView
.
我怎样才能实现这一点,以便UIScrollView
在我更改内容时调整大小并正确布置其内容UITableView
?我目前正在使用自动布局.
rob*_*off 94
首先,那些其他视图(表格视图的兄弟姐妹)是否严格在表格视图的上方和下方?如果是这样,您是否考虑让表视图正常滚动,并将这些外部视图放在表视图的页眉和页脚视图中?然后你不需要滚动视图.
其次,您可能需要阅读技术说明TN2154:UIScrollView和Autolayout(如果您还没有).
第三,根据该技术说明中的信息,我可以想出几种方法来做你想做的事情.最干净的可能是创建一个UITableView
实现该intrinsicContentSize
方法的子类.实施是微不足道的:
@implementation MyTableView
- (CGSize)intrinsicContentSize {
[self layoutIfNeeded]; // force my contentSize to be updated immediately
return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
}
@end
Run Code Online (Sandbox Code Playgroud)
然后让自动布局使用表格视图的内在内容大小.在滚动视图(包括表视图)的子视图之间创建约束以将它们布局,并确保滚动视图的所有四个边都有约束.
您可能需要invalidateIntrinsicContentSize
在适当的时间发送到表视图(当您添加或删除行或更改行的高度时).你可能只是覆盖适当的方法MyTableView
来做到这一点.例如做[self invalidateIntrinsicContentSize]
的-endUpdates
,-reloadData
,- insertRowsAtIndexPaths:withRowAnimation:
,等.
这是我测试的结果:
滚动视图具有浅蓝色背景.红色顶部标签和蓝色底部标签是滚动视图内的表视图的兄弟.
这是我测试中视图控制器的完整源代码.没有xib文件.
#import "ViewController.h"
#import "MyTableView.h"
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end
@implementation ViewController
- (void)loadView {
UIView *view = [[UIView alloc] init];
self.view = view;
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor cyanColor];
[view addSubview:scrollView];
UILabel *topLabel = [[UILabel alloc] init];
topLabel.translatesAutoresizingMaskIntoConstraints = NO;
topLabel.text = @"Top Label";
topLabel.backgroundColor = [UIColor redColor];
[scrollView addSubview:topLabel];
UILabel *bottomLabel = [[UILabel alloc] init];
bottomLabel.translatesAutoresizingMaskIntoConstraints = NO;
bottomLabel.text = @"Bottom Label";
bottomLabel.backgroundColor = [UIColor blueColor];
[scrollView addSubview:bottomLabel];
UITableView *tableView = [[MyTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
tableView.translatesAutoresizingMaskIntoConstraints = NO;
tableView.dataSource = self;
tableView.delegate = self;
[scrollView addSubview:tableView];
UILabel *footer = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
footer.backgroundColor = [UIColor greenColor];
footer.text = @"Footer";
tableView.tableFooterView = footer;
NSDictionary *views = NSDictionaryOfVariableBindings(
scrollView, topLabel, bottomLabel, tableView);
[view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|[scrollView]|"
options:0 metrics:nil views:views]];
[view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[scrollView]|"
options:0 metrics:nil views:views]];
[view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|[topLabel][tableView][bottomLabel]|"
options:0 metrics:nil views:views]];
[view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[topLabel]|"
options:0 metrics:nil views:views]];
[view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-8-[tableView]-8-|"
options:0 metrics:nil views:views]];
[view addConstraint:[NSLayoutConstraint
constraintWithItem:tableView attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:view attribute:NSLayoutAttributeWidth
multiplier:1 constant:-16]];
[view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[bottomLabel]|"
options:0 metrics:nil views:views]];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.textLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];
return cell;
}
@end
Run Code Online (Sandbox Code Playgroud)
小智 54
除了rob的答案之外,还有UITableView的可自调整大小的子类的快速示例:
Swift 2.x
class IntrinsicTableView: UITableView {
override var contentSize:CGSize {
didSet {
self.invalidateIntrinsicContentSize()
}
}
override func intrinsicContentSize() -> CGSize {
self.layoutIfNeeded()
return CGSizeMake(UIViewNoIntrinsicMetric, contentSize.height)
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 3.x或Swift 4.x
class IntrinsicTableView: UITableView {
override var contentSize:CGSize {
didSet {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
self.layoutIfNeeded()
return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
}
}
Run Code Online (Sandbox Code Playgroud)
我用它将表视图放到另一个可自动调整大小的表视图的单元格中.
Kle*_*men 10
这是obj-C版本.它基于用户@MuHAOS的解决方案
@implementation SizedTableView
- (void)setContentSize:(CGSize)contentSize {
[super setContentSize:contentSize];
[self invalidateIntrinsicContentSize];
}
- (CGSize)intrinsicContentSize {
[self layoutIfNeeded]; // force my contentSize to be updated immediately
return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
}
@end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
36557 次 |
最近记录: |