我无法调整tableHeaderView的大小。它简单无效。
1)创建一个UITableView和UIView(100 x 320 px);
2)将UIView设置为UITableView的tableHeaderView;
3)Build and Go。一切都很好。
现在,我想调整tableHeaderView的大小,所以我在viewDidLoad中添加了这段代码:
self.tableView.autoresizesSubviews = YES;
self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;
CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;
tableHeaderView的高度应显示为200,但显示为100。
如果我写:
self.tableView.autoresizesSubviews = YES;
CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;
self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;
然后它按照我想要的200高度开始。但我希望能够在运行时修改它。
我也试过这个,没有成功:
self.tableView.autoresizesSubviews = YES;
self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;
CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;
[self.tableView.tableHeaderView setNeedsLayout];
[self.tableView.tableHeaderView setNeedsDisplay];
[self.tableView setNeedsLayout];
[self.tableView setNeedsDisplay];
这里的要点是:我们如何在运行时调整tableHeaderView的大小?
有人能够这样做吗?
由于
IME
答案 0 :(得分:179)
仅供参考:我通过修改tableHeaderView并重新设置它来实现这一点。在这种情况下,当UIWebView子视图完成加载时,我正在调整tableHeaderView的大小。
[webView sizeToFit];
CGRect newFrame = headerView.frame;
newFrame.size.height = newFrame.size.height + webView.frame.size.height;
headerView.frame = newFrame;
[self.tableView setTableHeaderView:headerView];
答案 1 :(得分:12)
这个答案很老,显然在iOS 7及更高版本上无效。
我遇到了同样的问题,我也希望更改动画,所以我为我的标题视图创建了UIView的子类并添加了这些方法:
- (void)adjustTableHeaderHeight:(NSUInteger)newHeight{
NSUInteger oldHeight = self.frame.size.height;
NSInteger originChange = oldHeight - newHeight;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
newHeight);
for (UIView *view in [(UITableView *)self.superview subviews]) {
if ([view isKindOfClass:[self class]]) {
continue;
}
view.frame = CGRectMake(view.frame.origin.x,
view.frame.origin.y - originChange,
view.frame.size.width,
view.frame.size.height);
}
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[(UITableView *)self.superview setTableHeaderView:self];
}
这实际上动画了UITableView的所有子视图,这些子视图与调用类的类类型不同。在动画结束时,它在superview(UITableView)上调用setTableHeaderView - 如果没有这个,UITableView内容将在用户下次滚动时跳回。到目前为止,我发现的唯一限制是,如果用户在动画发生时尝试滚动UITableView,滚动将动画,好像标题视图尚未调整大小(如果动画是动画,则不是很重要)快)。
答案 2 :(得分:10)
如果您想有条件地为更改设置动画,可以执行以下操作:
- (void) showHeader:(BOOL)show animated:(BOOL)animated{
CGRect closedFrame = CGRectMake(0, 0, self.view.frame.size.width, 0);
CGRect newFrame = show?self.initialFrame:closedFrame;
if(animated){
// The UIView animation block handles the animation of our header view
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
// beginUpdates and endUpdates trigger the animation of our cells
[self.tableView beginUpdates];
}
self.headerView.frame = newFrame;
[self.tableView setTableHeaderView:self.headerView];
if(animated){
[self.tableView endUpdates];
[UIView commitAnimations];
}
}
请注意,动画是双折的:
tableHeaderView
下方单元格的动画。这是使用beginUpdates
和endUpdates
UIView
动画块完成的。 为了同步这两个动画,animationCurve
必须设置为UIViewAnimationCurveEaseInOut
,持续时间设置为0.3
,这似乎是UITableView用于动画的时间。
我在gihub上创建了一个Xcode项目,它就是这样做的。 查看besi/ios-quickies
中的项目ResizeTableHeaderViewAnimated
答案 3 :(得分:8)
我认为如果你只设置myHeaderView的高度就可以了:
CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;
self.tableView.tableHeaderView = myHeaderView;
答案 4 :(得分:6)
在iOS 7之前使用@garrettmoon解决方案。
这是基于@ garrettmoon的更新解决方案:
- (void)adjustTableHeaderHeight:(NSUInteger)newHeight animated:(BOOL)animated {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:[CATransaction animationDuration]];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
newHeight);
[(UITableView *)self.superview setTableHeaderView:self];
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[(UITableView *)self.superview setTableHeaderView:self];
}
答案 5 :(得分:5)
这在iOS 7和8上适用于我。此代码在表视图控制器上运行。
[UIView animateWithDuration:0.3 animations:^{
CGRect oldFrame = self.headerView.frame;
self.headerView.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newHeight);
[self.tableView setTableHeaderView:self.headerView];
}];
答案 6 :(得分:4)
它因为tableHeaderView的设置者。
在设置tableHeaderView之前,必须设置UIView高度。 (如果Apple开源这个框架会更容易......)
答案 7 :(得分:3)
在iOS 9及更低版本中,tableHeaderView
在调整大小后不会重新布局。
此问题已在iOS 10中解决。
要解决此问题,请使用以下代码执行此操作:
self.tableView.tableHeaderView = self.tableView.tableHeaderView;
答案 8 :(得分:2)
在iOS 9.x上,在viewDidLoad
上执行此操作就可以了:
var frame = headerView.frame
frame.size.height = 11 // New size
headerView.frame = frame
headerView
被声明为@IBOutlet var headerView: UIView!
,并在故事板上连接,它位于tableView的顶部,用作tableHeaderView。
答案 9 :(得分:1)
在tableView.tableHeaderView
中为标题视图属性viewDidLoad
设置高度似乎不起作用,标题视图高度仍未按预期更改。
经过多次尝试打击这个问题。我发现,你可以通过调用标题视图创建逻辑来改变高度
- (void)didMoveToParentViewController:(UIViewController *)parent
方法。
因此示例代码如下所示:
- (void)didMoveToParentViewController:(UIViewController *)parent {
[super didMoveToParentViewController:parent];
if ( _tableView.tableHeaderView == nil ) {
UIView *header = [[[UINib nibWithNibName:@"your header view" bundle:nil] instantiateWithOwner:self options:nil] firstObject];
header.frame = CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), HeaderViewHeight);
[_tableView setTableHeaderView:header];
}
}
答案 10 :(得分:1)
用于5个经过测试的代码
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let headerView = self.tblProfile.tableHeaderView else {
return
}
let size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
if headerView.frame.size.height != size.height {
headerView.frame.size.height = size.height
self.tblProfile.tableHeaderView = headerView
self.tblProfile.layoutIfNeeded()
}
}
注意::您需要从上,下,前,尾给出所有子视图的约束。这样它将获得整个所需的大小。
引用来自: https://useyourloaf.com/blog/variable-height-table-view-header/
答案 11 :(得分:0)
我发现UIView的initWithFrame初始化程序没有正确地遵守我传入的矩形。因此,我做了以下完美的工作:
- (id)initWithFrame:(CGRect)aRect {
CGRect frame = [[UIScreen mainScreen] applicationFrame];
if ((self = [super initWithFrame:CGRectZero])) {
// Ugly initialization behavior - initWithFrame will not properly honor the frame we pass
self.frame = CGRectMake(0, 0, frame.size.width, 200);
// ...
}
}
这样做的好处是可以更好地封装到您的视图代码中。
答案 12 :(得分:0)
我已经实现了表格标题的动画高度更改,以便在点按时展开到整个屏幕。但是,代码可以在其他情况下提供帮助:
// Swift
@IBAction func tapped(sender: UITapGestureRecognizer) {
self.tableView.beginUpdates() // Required to update cells.
// Collapse table header to original height
if isHeaderExpandedToFullScreen {
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.scrollView.frame.size.height = 110 // original height in my case is 110
})
}
// Expand table header to overall screen
else {
let screenSize = self.view.frame // "screen" size
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.scrollView.frame.size.height = screenSize.height
})
}
self.tableView.endUpdates() // Required to update cells.
isHeaderExpandedToFullScreen= !isHeaderExpandedToFullScreen // Toggle
}
答案 13 :(得分:0)
我想要UITableView
作为表的标题UISearchBar
,所以我有一个看起来像这样的层次结构
UITableView
|
|--> UIView
| |--> UISearchBar
|
|--> UITableViewCells
正如其他地方所述,如果您在更改后没有设置TableViewHeader,则不会发生任何事情。
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = YES;
[UIView animateWithDuration:0.2f animations:^{
[searchBar sizeToFit];
CGFloat height = CGRectGetHeight(searchBar.frame);
CGRect frame = self.tableView.tableHeaderView.frame;
frame.size.height = height;
self.tableHeaderView.frame = frame;
self.tableView.tableHeaderView = self.tableHeaderView;
}];
[searchBar setShowsCancelButton:YES animated:YES];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = NO;
[UIView animateWithDuration:0.f animations:^{
[searchBar sizeToFit];
CGFloat height = CGRectGetHeight(searchBar.frame);
CGRect frame = self.tableView.tableHeaderView.frame;
frame.size.height = height;
self.tableHeaderView.frame = frame;
self.tableView.tableHeaderView = self.tableHeaderView;
}];
[searchBar setShowsCancelButton:NO animated:YES];
return YES;
}
答案 14 :(得分:0)
如果使用autolayout设计自定义headerView,则需要在web-fetch或类似的懒惰任务之后更新headerView。 然后在 iOS-Swift 中我做了这个并使用以下代码更新了headerView:
//to reload your cell data
self.tableView.reloadData()
dispatch_async(dispatch_get_main_queue(),{
// this is needed to update a specific tableview's headerview layout on main queue otherwise it's won't update perfectly cause reloaddata() is called
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
答案 15 :(得分:0)
显然,到目前为止,Apple应该已经为tableHeaderView&实现了UITableViewAutomaticDimension。 tableFooterView ...
以下似乎对我使用布局约束:
CGSize s = [ self systemLayoutSizeFittingSize : UILayoutFittingCompressedSize ];
CGRect f = [ self frame ];
f.size = s;
[ self setFrame : f ];
答案 16 :(得分:0)
如果tableHeaderView是内容可调的WebView,则可以尝试:
[self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
self.webView.height = self.webView.scrollView.contentSize.height;
self.tableView.tableHeaderView = self.webView;
}
我在iOS9和iOS11上进行了测试,效果很好。
答案 17 :(得分:0)
仅当您使用自动布局并将translatesAutoresizingMaskIntoConstraints = false
设置为自定义标题视图时,此选项才适用。
最好和最简单的方法是覆盖intrinsicContentSize
。 UITableView
在内部使用intrinsicContentSize
来确定其页眉/页脚大小。在自定义视图中覆盖intrinsicContentSize
后,您需要执行的操作如下
invalidateIntrinsicContentSize()
tableView.setNeedsLayout()
和tableView.layoutIfNeeded()
然后UITableView
的页眉/页脚将根据需要进行更新。无需将视图设置为零或重置。
UITableView.tableHeaderView
或.tableFooterView
真正有趣的一件事是UIStackView
失去了管理arrangedSubviews
的能力。如果要将UIStackView
用作tableHeaderView或tableFooterView,则必须将stackView嵌入UIView
中,并覆盖UIView
的{{1}}。
答案 18 :(得分:-3)
[self.tableView reloadData]
?