调整大小后如何调整 UINavigationController 的视图控制器框架的大小

Posted

技术标签:

【中文标题】调整大小后如何调整 UINavigationController 的视图控制器框架的大小【英文标题】:How to resize UINavigationController's view controllers frame after it is resized 【发布时间】:2014-08-23 22:43:09 【问题描述】:

我有一个 UINavigationController 作为子视图控制器添加到容器 UIViewController 类中。我需要在导航控制器的视图上方动态显示横幅视图。我调整了导航控制器视图的大小,但我无法调整导航控制器的子视图控制器视图的大小。

// 此代码更新导航控制器的视图,但不更新其子视图控制器视图的高度。

self.updateViewYOffset(self.rootNavigationController.view, yOffset: yOffset)

func updateViewYOffset(view: UIView, yOffset: CGFloat) 
    var frame = view.frame
    frame.origin.y = yOffset
    frame.size.height = self.view.frame.size.height - yOffset
    view.frame = frame

// 如果 iPhone 5s - 导航控制器的视图高度现在是 538 (568-30) 但其子视图控制器的视图高度仍然是 568。

【问题讨论】:

这看起来不像您的实际代码 - 您在 frame 变量中获取并设置导航控制器的 view(一个 UIView),但像操作视图的框架(一个CG矩形)。您可以发布您正在使用的代码吗? @Tim 我已经编辑了代码。 rootNavigationController 的根视图控制器的 tableview 的框架没有得到更新。 你确定要在 viewDidLayoutSubviews() 中布局所有东西吗?我遇到了这个问题,并通过确保我的所有子视图都以这种方法布局来解决它。显然,您没有立即在 viewDidLoad() 中获得正确的视图框架 【参考方案1】:

我刚刚实现了类似的东西。您可能已经想出了一个解决方案,但对于未来的访客,我将解释我做了什么。

我创建了 UIViewController 的自定义子类,我们称之为 AppContainerController,它实际上将顶部横幅视图(在我的例子中作为 UIButton)设置为子视图。然后我有一个方法 -setMainViewController(controller:UIViewController) 将该控制器的视图添加到我的 AppContainerController 并设置框架以填充整个视图。

在我的 AppDelegate 中,我将此 AppContainerController 设置为窗口的 rootViewController。然后我使用 AppContainerController#setMainViewController(...) 添加一个 UINavigationController。当我想显示横幅视图时,我可以调整 mainViewController 视图的框架,并允许横幅(UIButton)框架更大。所有这些都可以动画化。这是 AppContainerController 的代码。

class KLAppContainerController: UIViewController 

var activeTourBanner:UIButton!
var mainViewController:UIViewController?
let bannerHeight:CGFloat = 44.0

let s = String(format: "s%@a%@u%@B%@r%@i%@d%@w", "t", "t", "s", "a", "W", "n", "o")

override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)  
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    self.modalPresentationStyle = .CurrentContext


required init(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")


override func preferredStatusBarStyle() -> UIStatusBarStyle 
    return .LightContent


func setMainViewController(controller:UIViewController) 

    var topViewFrame = self.view.bounds

    if let mvc = self.mainViewController 
        topViewFrame = mvc.view.frame
        mvc.view.frame = self.view.bounds
        mvc.view.removeFromSuperview()
        mvc.willMoveToParentViewController(nil)
        mvc.removeFromParentViewController()
    

    // assign new controller to mainViewController
    self.mainViewController = controller

    // add child controller to this View Controller
    self.addChildViewController(self.mainViewController!)

    self.mainViewController!.didMoveToParentViewController(self)
    self.mainViewController!.view.autoresizingMask = autoResizeToFillScreen()
    self.mainViewController!.view.frame = topViewFrame

    self.view.addSubview(self.mainViewController!.view)


func autoResizeToFillScreen() -> UIViewAutoresizing 
    return (.FlexibleWidth |
        .FlexibleHeight |
        .FlexibleTopMargin |
        .FlexibleBottomMargin |
        .FlexibleLeftMargin |
        .FlexibleRightMargin)


func setupActiveTourBanner() 
   // upperContentView = UIView(frame: self.view.bounds)
    //self.view.addSubview(upperContentView)
    self.activeTourBanner = UIButton.buttonWithType(.Custom) as UIButton
    self.activeTourBanner.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), bannerHeight)
    self.activeTourBanner.setTitle("Tap here to continue the tour", forState: .Normal)
    NUIRenderer.renderButton(self.activeTourBanner, withClass:"ActiveTourButton")
    self.activeTourBanner.addTarget(self, action: "activeTourButtonTapped", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(self.activeTourBanner)
    self.activeTourBanner.hidden = true
    self.hideActiveTourBanner()


func showActiveTourBanner(tour:KLTour) 

    let bannerRect = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), bannerHeight)
    let controllerRect = CGRectMake(0, bannerHeight, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - bannerHeight)
    var sw = UIApplication.sharedApplication().valueForKey(s) as UIWindow

    self.activeTourBanner.hidden = false

    UIView.animateWithDuration(0.2, animations:  () -> Void in
        sw.frame = CGRectMake(0, self.bannerHeight, CGRectGetWidth(sw.frame), CGRectGetHeight(sw.frame))
        self.activeTourBanner.frame = bannerRect
        self.mainViewController!.view.frame = controllerRect
    )  (Bool) -> Void in

    


func hideActiveTourBanner() 
    var barRect = self.activeTourBanner.frame
    barRect.origin.y = -barRect.size.height
    let controllerRect = self.view.bounds

    var sw = UIApplication.sharedApplication().valueForKey(s) as UIWindow

    UIView.animateWithDuration(0.2, animations:  () -> Void in
        self.mainViewController!.view.frame = controllerRect
        self.activeTourBanner.frame = barRect
        sw.frame = CGRectMake(0, 0, CGRectGetWidth(sw.frame), CGRectGetHeight(sw.frame))
        , completion:  (Bool) -> Void in
            self.activeTourBanner.hidden = true
    )


// MARK: - Handlers
func activeTourButtonTapped() 
    self.hideActiveTourBanner()

【讨论】:

以上是关于调整大小后如何调整 UINavigationController 的视图控制器框架的大小的主要内容,如果未能解决你的问题,请参考以下文章

创建特定窗口后如何调整其大小?

调整大小后如何保持表单居中在屏幕中间

旋转后调整大小时如何计算平移x和y值..?

自动调整大小后如何获得框架位置?

调整大小后通过鼠标连续调整其余图像的大小,并保持比例

如何在单元格大小更改后自动调整 CollectionViewCell 中的内容大小?