Ken*_*art 44 layout uiviewcontroller ios xamarin
考虑以下控制器层次结构:
UINavigationController
UIViewController
UITableViewController存在UIViewController影响布局.没有它,它UITableViewController占据了整个范围UINavigationController:

但是,如果我UIViewController在UINavigationController和之间添加一个香草,则UITableViewController在顶部UIViewController和顶部之间出现一个20px的间隙UITableViewController:

即使我将代码减少到最简单的事情,我仍然会观察到这种行为.考虑这个应用程序委托代码:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
window = new UIWindow(UIScreen.MainScreen.Bounds);
var tableView = new UITableViewController();
var intermediateView = new UIViewController();
var navigation = new UINavigationController(intermediateView);
navigation.View.BackgroundColor = UIColor.Red;
intermediateView.View.BackgroundColor = UIColor.Green;
tableView.View.BackgroundColor = UIColor.Blue;
intermediateView.AddChildViewController(tableView);
intermediateView.View.AddSubview(tableView.View);
tableView.DidMoveToParentViewController(intermediateView);
window.RootViewController = navigation;
window.MakeKeyAndVisible();
return true;
}
Run Code Online (Sandbox Code Playgroud)
上面仍然显示了顶部UIView和顶部之间的20px间隙UITableView.
我知道有些东西错误地为状态栏分配空间.使用Reveal我可以看到Frame的UITableViewController具有Y的价值20.
WantsFullScreenLayout于true上UIViewController,UITableViewController和两个EdgesForExtendedLayout,并ExtendedLayoutIncludesOpaqueBars同时为UIViewController和UITableViewControllerAutomaticallyAdjustsScrollViewInsets上了UIViewControllerPreservesSuperviewLayoutMargins的UITableViewPrefersStatusBarHidden并返回true在两个UIViewController和UITableViewController压倒ViewDidLayoutSubviews我的UITableViewController:
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
this.View.Frame = this.View.Superview.Bounds;
}
Run Code Online (Sandbox Code Playgroud)
UIViewController?的UITableViewController?ViewDidLayoutSubviews我的视图控制器与对视觉树中显示位置的期望结合起来.如果将它托管在控制器堆栈的更高位置,事情看起来就不对了.有没有办法避免这种耦合,从而提高可重用性?Dan*_*sko 36
您所看到的行为根本不是一个错误,而只是您滥用将视图添加到层次结构中的副作用.
当您将tableView添加到视图中时,您需要告诉UIKit您希望tableView相对于其父级的大小.您有两个选项:自动布局或自动调整蒙版.如果没有描述您希望视图布局的方式,UIKit只需将其弹出到层次结构上,默认实现将您的视图放在顶部布局指南下(恰好是状态栏的高度).像这样简单的东西可以解决问题:
tableVC.View.Frame = rootVC.View.Bounds
tableVC.View.Autoresizingmask = UIViewAutoresizing.FlexibleWidth
tableVC.View.TranslatesAutoresizingMaskIntoConstraints = true// always nice to explicitly use auto layout
Run Code Online (Sandbox Code Playgroud)
此行为实际上并不是独占的,UITableViewController而且也是UICollectionViewController.我相信他们的默认viewLoading实现会在状态栏下隐藏视图.如果我们使childController成为一个简单的UIViewController子类,则不会出现这种行为.不要认为这是一个bug,如果你明确声明你希望如何布置他们各自的观点,你就不会有这个问题.当然,这是容器控制器的主要功能.
你的appDelegate应该是什么样子:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
window = new UIWindow(UIScreen.MainScreen.Bounds);
var tableVC = new UITableViewController();
var rootVC = new UIViewController();
var navigationVC = new UINavigationController(intermediateView);
navigationVC.View.BackgroundColor = UIColor.Red;
rootVC.View.BackgroundColor = UIColor.Green;
tableVC.View.BackgroundColor = UIColor.Blue;
rootVC.AddChildViewController(tableVC);
rootVC.View.AddSubview(tableVC.View);
//YOU NEED TO CONFIGURE THE VIEWS FRAME
//If you comment this out you will see the green view under the status bar
tableVC.View.Frame = rootVC.View.Bounds
tableVC.View.Autoresizingmask = UIViewAutoresizing.FlexibleWidth
tableVC.View.TranslatesAutoresizingMaskIntoConstraints = true
tableVC.DidMoveToParentViewController(rootVC);
window.RootViewController = navigationVC;
window.MakeKeyAndVisible();
return true;
}
Run Code Online (Sandbox Code Playgroud)
var window: UIWindow?
var navigationControlller: UINavigationController!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let rootVC = UIViewController(nibName: nil, bundle: nil)
let tableVC = UITableViewController(style: .Plain)
let navVC = UINavigationController(rootViewController: rootVC)
navVC.navigationBarHidden = true
navVC.view.backgroundColor = UIColor.redColor()
rootVC.view.backgroundColor = UIColor.greenColor()
rootVC.view.addSubview(tableVC.view)
//YOU NEED TO CONFIGURE THE VIEWS FRAME
//If you comment this out you will see the green view under the status bar
tableVC.view.frame = rootVC.view.bounds
tableVC.view.autoresizingMask = .FlexibleWidth | .FlexibleHeight
tableVC.view.setTranslatesAutoresizingMaskIntoConstraints(true)
rootVC.addChildViewController(tableVC)
tableVC.didMoveToParentViewController(rootVC)
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.rootViewController = navVC
window?.makeKeyAndVisible()
return true
}
Run Code Online (Sandbox Code Playgroud)
注意我最近写了一篇文章,描述了配置视图以填充其超级视图的方法
您的问题似乎与UITableViewController直接添加为另一个的子控制器的某些基本问题有关.
环顾这个并不是一个新问题:iOS 7:UITableView显示在状态栏下
相对于那篇文章,我拿了你的代码并尝试了以下选项(一旦我意识到它是在C#8 ^)):
而不是使用UITableViewController,添加一个UIViewController
,然后添加一个UITableView作为孩子的UIViewController.如果你这样做,那么就没有20pt的问题.这突出表明问题出在UITableViewController班上.
这种方法是一个相对干净的解决方法,只有几个额外的步骤你已经.
我尝试在原始代码中添加约束来强制UITableViewController框架到顶部,但无法使其工作.再次,这可能是由于表控制器覆盖了事物本身.
如果您使用故事板构建演示,一切正常.我相信这是因为IB本身使用容器视图来嵌入新的视图控制器.因此,如果您使用storyboard,那么apple的方式是添加一个视图,您可以设置使用约束的框架,然后UITableViewController通过嵌入Segue将视图嵌入到该视图中.
因此,根据1),使用中间的视图似乎解决了问题,并且似乎控制中间视图似乎frame
是关键.
我注意到你唯一可行的解决方法是改变框架就是答案.但是在iOS7之后,似乎没有推荐更改框架,因为它可能会与想要操纵框架的约束发生冲突.
edgesForExtendedLayout所有其他选项似乎都失败了.这些似乎是容器视图控制器的提示,UITableViewController忽略它们.恕我直言我认为选项1)似乎是最安全的方法,因为你可以完全控制布局,并且不会使用帧覆盖来对抗系统,这可能会导致你以后出现问题.选项2)只有在使用故事板时才能真正起作用.您可以尝试自己手动执行相同的操作,但是谁知道嵌入Segue中发生了什么.
编辑
似乎Arkadiusz Holko在他的回答中突出显示了一个缺失的步骤,并且明确地为表视图设置框架确实解决了问题.
添加子视图控制器时,您错过了一步 - 设置其视图的框架.
见第二步:
- (void) displayContentController: (UIViewController*) content;
{
[self addChildViewController:content]; // 1
content.view.frame = [self frameForContentController]; // 2
[self.view addSubview:self.currentClientView];
[content didMoveToParentViewController:self]; // 3
}
Run Code Online (Sandbox Code Playgroud)
资料来源:https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html
| 归档时间: |
|
| 查看次数: |
7781 次 |
| 最近记录: |