我很难在UITableViewController的viewDidLoad方法中添加子视图(UIView)
这有效:
[self.view addSubview:self.progView];
但是你可以通过UIView progView看到表格单元格出血。
我尝试过这种方法:
[self.view.superview insertSubview:self.progView aboveSubview:self.view];
尝试将progView,UIView添加到当前视图上方的superview。当我尝试这个时,UIView永远不会出现。
- 更新 -
以下是最新的尝试:
UIView *myProgView = (UIView *)self.progView; //progView is a method that returns a UIView
[self.tableView insertSubview:myProgView aboveSubview:self.tableView];
[self.tableView bringSubviewToFront:myProgView];
结果与[self.view addSubview:self.progView]相同; UIView出现但似乎在桌子后面。
答案 0 :(得分:93)
我尝试了上面的方法,但没有让它发挥作用。我还发现它需要太多的配置和代码,因为它需要从头开始设置表视图(这可以从故事板中轻松完成)。
相反,我添加了一个视图,我想将我的UITableView添加到UITableViewController的UINavigationController视图中,如下所示:
[self.navigationController.view addSubview:<view to add above the table view>];
这种方法要求您已将UITableViewController嵌入到UINavigationController中,但即使您不需要导航控制器,仍然可以使用此方法并隐藏导航栏。
答案 1 :(得分:28)
这实际上非常简单易行 - 只需要一些重新布线。我遇到了类似的情况,并将其编码为允许我在表格视图的顶部添加加载屏幕。此方法还允许您将静态表格单元格与您自己的内容一起使用。
如果您的控制器是Storyboard或XIB中的UITableViewController,并且您希望在保留现有表视图的同时将self.view重新分配给标准UIView:
将这些实例变量添加到标题文件:
IBOutlet UITableView *tableViewReference; // to keep a reference to the tableview
UIView *viewReference; // a reference to the new background view
在 Storyboard或XIB文件中:将tableView
中的UITableViewController
与tableViewReference
变量相关联。
然后在实施文件:
中// Override the default accessors of the tableview and view
- (UITableView*)tableView { return tableViewReference; }
- (UIView*)view { return viewReference; }
- (void)viewDidLoad
{
[super viewDidLoad];
// instantiate the new self.view, similar to the tableview
viewReference = [[UIView alloc] initWithFrame:tableViewReference.frame];
[viewReference setBackgroundColor:tableViewReference.backgroundColor];
viewReference.autoresizingMask = tableViewReference.autoresizingMask;
// add it as a subview
[viewReference addSubview:tableViewReference];
/* remainder of viewDidLoad */
}
虽然看起来很奇怪,但UITableViewController在幕后引用很多古怪的东西。您需要等到viewDidLoad才能进行交换。在此之后,访问者将指向正确的UIView
和UITableView
。
使用方法: 像
这样的东西 [self.view addSubview:myView];
会在表格视图前添加UIView myView
,而不会myView
滚动表格视图的内容。
注意:在指出该解决方案包含临界矛盾代码后,对此答案进行了编辑。 UITableViewController对它所拥有的引用做了一些奇怪的事情。一些更仔细的测试得出了这个更简单的答案:)
答案 2 :(得分:11)
您可以增加视图图层的zPosition。
这将使其显示在其他视图上方(默认情况下zPosition等于0)
self.progView.layer.zPosition++;
[self.view addSubview:self.progView];
答案 3 :(得分:11)
我已经能够使用uiviewcontroller包含在uitableviewcontroller上添加子视图。
UITableViewController在静态单元格方面实际上非常方便,这可能是唯一一个“只使用uitableview”的常见答案实际上不可行的时候。
所以我就是这样做的。
添加如下代码:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UITableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"MyStaticTableView"];
[self addChildViewController:vc];
[self.view_container addSubview:vc.view];
}
您可能遇到的问题:
添加代码:
- (void)viewWillAppear:(BOOL)animated
{
[[self.view_container.subviews lastObject] setFrame:self.view.frame];
}
此时,您可以从UITableViewController直接使用
访问容器视图self.view.superview.superview
并且您添加到它的任何内容都将显示在您的表视图控制器
上答案 4 :(得分:7)
以下是故事板的方式:
2)将它与UITableViewController类链接:
@IBOutlet weak var copyrightLabel: UILabel!
3)将其添加到代码中
self.navigationController?.view.addSubview(copyrightView)
copyrightView.frame = CGRect(x: 0,
y: self.view.bounds.size.height - copyrightView.bounds.size.height,
width: self.view.bounds.size.width,
height: copyrightView.bounds.size.height)
视图不会随表格视图滚动。它可以从故事板中轻松设计。
答案 5 :(得分:6)
问题是view
的{{1}}属性与UITableViewController
属性相同。这意味着根视图总是一个表视图控制器,任何作为子视图添加的内容都将受到表视图功能的限制。这有其他不良副作用,例如您可能不希望它们滚动的子视图。
这里有几个选项。您可以覆盖tableView
并安装自己的视图和表格视图:
loadView
然后,当您需要添加子视图时,请根据需要在// note: untested
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
self.view.backgroundColor = [UIColor whiteColor];
UITableView *tblView = [[UITableView alloc]
initWithFrame:CGRectZero
style:UITableViewStylePlain
];
tblView.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight
;
self.tableView = tblView;
[self.view addSubview:tblView];
[tblView release];
}
下方或上方添加。
另一个选择就是创建一个self.tableView
子类来完成你需要的工作。 UIViewController
老实说,并没有增加那么多,它实现的小功能很容易复制。像Recreating UITableViewController to increase code reuse这样的文章很容易解释如何做到这一点。
答案 6 :(得分:6)
我遇到了类似的问题,并使用以下代码解决了问题:
[self.navigationController.view insertSubview:<subview>
belowSubview:self.navigationController.navigationBar];
使用Stack中的控制器将视图插入到正确的位置。
答案 7 :(得分:6)
由于UITableViewController是UIViewController的子类,因此您需要将所需的视图添加到其superview中。
Swift:
self.view.superview?.addSubview(viewTobeAdded)
Objective C:
[self.view.superview addSubview: viewTobeAdded];
答案 8 :(得分:5)
Apple示例“iPhoneCoreDataRecipes”正在使用NIB将标头加载到UITableView上。 见here:
答案 9 :(得分:4)
我在桌子上方添加了一张图片。我用了这段代码:
self.tableView.tableHeaderView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"header.png"]];
答案 10 :(得分:2)
swift解决方案(相当于Daniel Saidi):
如果您的控制器是Storyboard或XIB中的UITableViewController,并且您希望在保留现有表视图的同时将self.view重新分配给标准UIView:
@IBOutlet var tableViewReference: UITableView!
var viewReference: UIView!
然后在您的实施文件中:
将这些实例变量添加到表视图控制器文件中:
override var tableView: UITableView! {
get { return tableViewReference }
set { super.tableView = newValue }
}
override var view: UIView! {
get { return viewReference }
set { super.view = newValue }
}
override func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = UIRectEdge.None
self.extendedLayoutIncludesOpaqueBars = false
self.automaticallyAdjustsScrollViewInsets = false
//rewiring views due to add tableView as subview to superview
viewReference = UIView.init(frame: tableViewReference.frame)
viewReference.backgroundColor = tableViewReference.backgroundColor
viewReference.autoresizingMask = tableViewReference.autoresizingMask
viewReference.addSubview(tableViewReference)
}
在Storyboard或XIB文件中:将UITableViewController中的tableView连接到tableViewReference变量。
然后您可以按如下方式添加子视图:
self.view.addSubView(someView)
答案 11 :(得分:2)
iOS 11更新:
现在可以在对安全区域使用AutoLayout约束时将子视图添加到UITableView
。这些视图不会沿着TableView滚动。
此示例将导航栏下方的视图放置在UITableView
UITableViewController
之上
[self.tableView addSubview:self.topBarView];
[NSLayoutConstraint activateConstraints:@[
[self.topBarView.topAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.topAnchor],
[self.topBarView.leadingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.leadingAnchor],
[self.topBarView.trailingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.trailingAnchor],
[self.topBarView.heightAnchor constraintEqualToConstant:40.0]
]];
答案 12 :(得分:1)
尝试:[self.view bringSubviewToFront:self.progView];
或者您可以尝试将self.progView
添加到表格视图中。
答案 13 :(得分:1)
要在当前UITableViewController上方添加customView,它必须是使用Daniel所评论的“ self.navigationController.view addSubview:customView”的好方法。
但是,如果实现实现用作navigationBar的customView,Daniel的方法可能会导致默认结果意外发生,或者导致UITableViewController前后的其他navigationViewController上的custom navigationBar出现意外情况。
最好的简单方法是将UITableViewController转换为UIViewController,对子视图的布局没有限制。但是,如果您要处理大量的,冗长的旧版UITableViewController代码,则情况完全不同。我们没有任何转换时间。
在这种情况下,您可以简单地劫持UITableViewController的tableView并解决整个问题。
我们应该知道的最重要的事情是UITableViewController的'self.view.superview'是nil,'self.view'是UITableView本身。
首先,劫持UITableVIew。
UITableView *tableView = self.tableView;
然后,用新的UIView替换'self.view'(现在为UITableView),以便我们可以无限制地布局customViews。
UIView *newView = UIView.new;
newView.frame = tableView.frame;
self.view = newView;
然后,将之前被劫持的UITableView放到新的self.view上。
[newView addSubview:tableView];
tableView.translatesAutoresizingMaskIntoConstraints = NO;
[tableView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
[tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
[tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
[tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
现在,我们可以在UITableViewController上这个崭新的'self.view'上做任何想要的事情。
自定义视图,然后将其添加为子视图。
UIView *myNaviBar = UIView.new;
[myNaviBar setBackgroundColor:UIColor.cyanColor];
[self.view addSubview:myNaviBar];
myNaviBar.translatesAutoresizingMaskIntoConstraints = NO;
[myNaviBar.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
[myNaviBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
[myNaviBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
[myNaviBar.heightAnchor constraintEqualToConstant:90].active = YES;
答案 14 :(得分:1)
快捷键4
这是我们在重新构建视图层次结构时所用答案的最简化版本。这种方法不需要为情节提要/笔尖提供额外的插座,并且还可以与以编程方式构造的实例一起使用。
class MyTableViewController: UITableViewController {
var strongTableView: UITableView?
override var tableView: UITableView! {
get {
return strongTableView ?? super.tableView
}
set {
strongTableView = newValue
}
}
override func viewDidLoad() {
super.viewDidLoad()
// theoretically we could use self.tableView = self.tableView but compiler will not let us assign a property to itself
self.tableView = self.view as? UITableView
self.view = UIView(frame: self.tableView!.frame)
self.view.addSubview(tableView)
}
}
答案 15 :(得分:1)
您可以简单地将以下代码放在viewDidAppear中:
[self.tableView.superview addSubview:<your header view>];
答案 16 :(得分:1)
使用一个(或多个)委托方法(UITableViewDelegate)将UIView保留在UITableViewController中的表视图之上。
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.addSubview(headerView)
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
tableView.addSubview(overlayView) // adds view always on top
}
// if using footers in table view
tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { ... }
由于视图只能有一个超级视图,接缝也是很好的解决方案,如果我错了,请纠正我。仍然得到60fps,这对我来说很好。
答案 17 :(得分:0)
这对我有用:
self.view.superview?.addSubview(yourCustomView)
self.view.bringSubviewToFront(yourCustomView)
答案 18 :(得分:0)
尝试这样的事情:
[self.tableView addSubview:overlayView];
overlayView.layer.zPosition = self.tableView.backgroundView.layer.zPosition + 1;
答案 19 :(得分:0)
可能有理由不这样做,但到目前为止这对我有用。如果你使用ap
在viewDidLayoutSubviews
内你可以运行它,但请确保只运行一次
self.searchTableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStylePlain];
self.searchTableView.backgroundColor = [UIColor purpleColor];
[self.view.superview addSubview:self.searchTableView];
答案 20 :(得分:0)
我有一个类似的问题,我想在我的UITableViewController上添加一个加载指示器。为了解决这个问题,我将我的UIView添加为窗口的子视图。这解决了这个问题。这就是我做到的。
-(void)viewDidLoad{
[super viewDidLoad];
//get the app delegate
XYAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
//define the position of the rect based on the screen bounds
CGRect loadingViewRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 50, 50);
//create the custom view. The custom view is a property of the VIewController
self.loadingView = [[XYLoadingView alloc] initWithFrame:loadingViewRect];
//use the delegate's window object to add the custom view on top of the view controller
[delegate.window addSubview: loadingView];
}