dynamic更改UITableView高度
我想改变我的tableview从另一个viewcontroller的高度基于其单元格的高度,因为它们是dynamic的。 这是否可能? 谢谢
加上:
我基本上有一个UserProfileViewController在屏幕的一半上有一个containerview。 在那里我添加了不同的其他视图控制器:
在墙上的button,这是我如何添加视图控制器和它的后续tableview:
- (IBAction)wallButtonPressed:(id)sender { //Check if there is an instance of the viewcontroller we want to display. If not make one and set it's tableview frame to the container's view bounds if(!_userWallViewController) { self.userWallViewController = [[WallViewController alloc] init]; // self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds; } [self.userWallViewController.containerView addSubview:self.userWallViewController.activityFeedTableView]; //If the currentviewcontroller adn it's view are already added to the hierarchy remove them [self.currentViewController.view removeFromSuperview]; [self.currentViewController removeFromParentViewController]; //Add the desired viewcontroller to the currentviewcontroller self.currentViewController = self.userWallViewController; //Pass the data needed for the desired viewcontroller to it's instances self.userWallViewController.searchURLString = [NSString stringWithFormat:@"event/user/%@/", self.userID]; self.userWallViewController.sendCommentURLString = [NSString stringWithFormat:@"event/message/%@", self.userID]; [self.userWallViewController.activityFeedTableView reloadData]; self.userWallViewController.totalCellHeight = ^(float totalCellHeight){ self.scrollView.contentSize = CGSizeMake(320.0, totalCellHeight); CGRect newFrame = self.userWallViewController.containerView.frame; newFrame.size.height = totalCellHeight + 33.0; self.userWallViewController.containerView.frame = newFrame; self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds; }; //Add this containerview to the desired viewcontroller's containerView self.userWallViewController.containerView = self.containerView; //Add the needed viewcontroller and view to the parent viewcontroller and the containerview [self addChildViewController:self.userWallViewController]; [self.containerView addSubview:self.userWallViewController.view]; //CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS [self.userFansViewController.userSimpleTableView removeFromSuperview]; [self.fanOfViewController.userSimpleTableView removeFromSuperview]; [self.userPublishedMovellaListViewController.gridView removeFromSuperview]; [self.userPublishedMovellaListViewController removeFromParentViewController]; self.userPublishedMovellaListViewController = nil; }
在这个viewcontroller这是我初始化我的tableview的地方:
-(UITableView *)activityFeedTableView { if (!_activityFeedTableView) { _activityFeedTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 850.0) style:UITableViewStylePlain]; } return _activityFeedTableView; }
我正在计算单元格高度的总和,问题是单元格的高度方法在调用tableview的getter之后被调用。 所以我需要某种方式来知道什么时候单元格的高度方法完成所有单元格,然后我可以调整我的tableview。 谢谢
根据tableview的内容,没有一个系统function来改变表的高度。 话虽如此,可以编程方式根据内容改变tableview的高度,具体是基于tableview的contentSize
(这比自己手动计算高度更容易)。 一些细节取决于你是否使用了iOS 6的一部分的新的自动布局。
但是假设你在viewDidLoad
configuration了你的表视图的底层模型,如果你想调整tableview的高度,你可以在viewDidAppear
做到这一点:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self adjustHeightOfTableview]; }
同样,如果你曾经为tableview执行reloadData
(或者添加或删除行),你也要确保你也手动调用了adjustHeightOfTableView
,例如:
- (IBAction)onPressButton:(id)sender { [self buildModel]; [self.tableView reloadData]; [self adjustHeightOfTableview]; }
所以问题是我们的adjustHeightOfTableview
应该做什么。 不幸的是,这是你是否使用iOS 6自动布局的一个function。 您可以通过打开故事板或NIB来确定是否打开了自动布局function,然后转到“文件检查器”(例如按下选项 + 命令 + 1或单击右侧面板上的第一个选项卡):
我们暂时假设自动布局已closures。 在这种情况下,它非常简单, adjustHeightOfTableview
只是调整tableview的frame
:
- (void)adjustHeightOfTableview { CGFloat height = self.tableView.contentSize.height; CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y; // if the height of the content is greater than the maxHeight of // total space on the screen, limit the height to the size of the // superview. if (height > maxHeight) height = maxHeight; // now set the frame accordingly [UIView animateWithDuration:0.25 animations:^{ CGRect frame = self.tableView.frame; frame.size.height = height; self.tableView.frame = frame; // if you have other controls that should be resized/moved to accommodate // the resized tableview, do that here, too }]; }
如果你的autolayout是打开的, adjustHeightOfTableview
会为你的tableview调整高度约束:
- (void)adjustHeightOfTableview { CGFloat height = self.tableView.contentSize.height; CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y; // if the height of the content is greater than the maxHeight of // total space on the screen, limit the height to the size of the // superview. if (height > maxHeight) height = maxHeight; // now set the height constraint accordingly [UIView animateWithDuration:0.25 animations:^{ self.tableViewHeightConstraint.constant = height; [self.view setNeedsUpdateConstraints]; }]; }
对于后一种基于约束的解决scheme来处理自动布局,我们必须首先处理几件事情:
-
通过点击这组button中的中心button,确保你的tableview有一个高度约束,然后select添加高度约束:
-
然后为该约束添加一个
IBOutlet
: -
请确保您调整其他约束,以便它们不冲突,如果您以编程方式resizetableview。 在我的例子中,tableview有一个拖尾的空间约束,将其locking在屏幕的底部,所以我不得不调整这个约束,以便不被locking在一个特定的大小,它可以大于或等于一个值,优先级较低,所以tableview的高度和顶部将决定一天:
你在这里做的其他限制完全取决于你在桌面下的屏幕上有什么其他的控制。 与往常一样,处理约束是有点尴尬的,但它确实有效,尽pipe在你的情况下,具体情况完全取决于你在场景中还有什么。 但希望你明白这个主意。 底线,与自动布局,确保调整你的其他约束(如果有的话)是灵活的,以解决变化的tableview高度。
正如你所看到的,如果你不使用autolayout,编程调整tableview的高度要容易得多,但是如果你是这样的话,我提出了两个select。
用xib或storyboard创build你的单元格。 给出它的内容。 现在在CellForRowAtIndexPath中调用它。 例如。 如果你想根据评论的标签文本设置单元格高度。
所以给你设置commentsLbl.numberOfLine = 0;
所以给你设置commentsLbl.numberOfLine = 0;
然后在ViewDidLoad中
self.table.estimatedRowHeight = 44.0 ; self.table.rowHeight = UITableViewAutomaticDimension;
现在
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return UITableViewAutomaticDimension;}
这可以用viewDidAppear中的一行代码进行大量简化:
override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) tableViewHeightConstraint.constant = tableView.contentSize.height }
Rob的解决scheme是非常好的,只有在他的-(void)adjustHeightOfTableview
方法的调用中
[self.view needsUpdateConstraints]
什么都不做,只是返回一个标志,而不是调用
[self.view setNeedsUpdateConstraints]
会产生预期的效果。
使用简单和简单的代码
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { let myCell = tableView.dequeueReusableCellWithIdentifier("mannaCustumCell") as! CustomCell let heightForCell = myCell.bounds.size.height; return heightForCell; }
为了调整我的表格,我在桌面视图控制器中使用了这个解决scheme,完全没问题:
[objectManager getObjectsAtPath:self.searchURLString parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { NSArray* results = [mappingResult array]; self.eventArray = results; NSLog(@"Events number at first: %i", [self.eventArray count]); CGRect newFrame = self.activityFeedTableView.frame; newFrame.size.height = self.cellsHeight + 30.0; self.activityFeedTableView.frame = newFrame; self.cellsHeight = 0.0; } failure:^(RKObjectRequestOperation *operation, NSError *error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; NSLog(@"Hit error: %@", error); }];
resize的部分是在一个方法,但这里只是你可以看到它。 现在我唯一的问题是调整其他视图控制器的滚动视图,因为我不知道什么时候tableview已经完成resize。 目前我正在执行与performSelector:afterDelay:但是这不是一个好办法做到这一点。 有任何想法吗?
这里的很多答案都没有兑现表格或者太复杂。 使用UITableView
的子类将正确设置intrinsicContentSize
是使用自动布局时更容易的解决scheme。 不需要高度限制等。
class UIDynamicTableView: UITableView { override var intrinsicContentSize: CGSize { self.layoutIfNeeded() return CGSize(width: UIViewNoIntrinsicMetric, height: self.contentSize.height) } override func reloadData() { super.reloadData() self.invalidateIntrinsicContentSize() } }
在界面生成器UIDynamicTableView
TableView的类设置为UIDynamicTableView
,并观察魔术,因为在调用reloadData()
之后,TableView将改变它的大小。
我发现添加约束比故事板更容易编程。
var leadingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.LeadingMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: 0.0) var trailingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: mView, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1, constant: 0.0) var height = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: screenSize.height - 55) var bottom = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.BottomMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1, constant: screenSize.height - 200) var top = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.TopMargin, multiplier: 1, constant: 250) self.view.addConstraint(leadingMargin) self.view.addConstraint(trailingMargin) self.view.addConstraint(height) self.view.addConstraint(bottom) self.view.addConstraint(top)