草庐IT

cocoa-touch - UINavigationController:将通用填充/边距应用于所有弹出 View Controller 的 View

coder 2024-01-28 原文

我有一个 UINavigationController,我希望弹出到堆栈上的每个 View Controller 的 View 都具有共同的填充/边距(例如,所有边均为 25 像素)。实现此目标的最佳方法是什么?

我最初认为我可以实现 UINavigationControllerDelegate 并在 navigationController:didShowViewController:animatednavigationController:willShowViewController:animated 方法中,只需更改即将显示的 View Controller 的框架。但这似乎没有效果。

我试图在 View Controller 的 viewDidAppearviewWillAppear 方法中做同样的事情,但这也没有用。理想情况下,无论如何我都不想在 Controller 中放置任何逻辑,因为它们可能并不总是在导航 Controller 中使用。

我还没有尝试过的最后一个想法是创建一个“包装器”UIViewController,它实际上会被推送到这个堆栈上。此包装器会将真实 View Controller 的 View 添加为 subview ,并带有可提供所需边距的框架。这里的缺点是我需要子类化 UINavigationController 并覆盖 pushViewController:animated,包装器将在其中被初始化和推送。 Apple 的文档表明 UINavigationController 不应该被子类化。

提前致谢。

最佳答案

我通过在 UIViewControllerview 而不是 UIViewController 周围放置一个“包装器”UIView 来解决这个问题> 本身。然后,包装器 View 通过在 layoutSubviews 方法中设置 subview 的框架来填充 subview 。

为方便起见,我附上了我使用的代码。要使用,请将 UINavigationController 替换为 PaddedNavigationController,并设置 PaddedNavigationControllerinsets 属性。

PaddedNavigationController.h:

#import <Foundation/Foundation.h>

@interface PaddedNavigationController : UINavigationController
{
    UIEdgeInsets _insets;
}

@property (nonatomic, assign) UIEdgeInsets insets;

@end

PaddedNavigationController.m:

#import "PaddedNavigationController.h"

@interface PaddedView : UIView
{
    UIView *_view;
    UIEdgeInsets _insets;
}

@property (nonatomic, assign) UIEdgeInsets insets;

+ (PaddedView *) wrapView:(UIView *)view withInsets:(UIEdgeInsets)insets;
- (id) initWithView:(UIView *)view insets:(UIEdgeInsets)insets;

@end


@implementation PaddedNavigationController

@synthesize insets = _insets;

- (void) pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    //check if the UIViewController's view has already been wrapped by the PaddedView; don't want to wrap it twice
    if(![viewController.view isKindOfClass:[PaddedView class]])
    {
        viewController.view = [PaddedView wrapView:viewController.view withInsets:self.insets];
    }
    [super pushViewController:viewController animated:animated];
}

- (void) setInsets:(UIEdgeInsets)insets
{
    _insets = insets;

    //loop through this navigation controller's view controllers and set the new insets on any PaddedViews
    for(UIViewController *viewController in self.viewControllers)
    {
        if([viewController.view isKindOfClass:[PaddedView class]])
        {
            PaddedView *padded = (PaddedView *)viewController.view;
            padded.insets = insets;
        }
    }
}

@end


@implementation PaddedView

@synthesize insets = _insets;

+ (PaddedView *) wrapView:(UIView *)view withInsets:(UIEdgeInsets)insets
{
    return [[[PaddedView alloc] initWithView:view insets:insets] autorelease];
}

- (id) initWithView:(UIView *)view insets:(UIEdgeInsets)insets
{
    if(self = [super initWithFrame:view.frame])
    {
        _insets = insets;
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _view = [view retain];
        [self addSubview:view];
    }
    return self;
}

- (void) dealloc
{
    [_view release];
    [super dealloc];
}

- (void) layoutSubviews
{
    //apply the insets to the subview
    _view.frame = CGRectMake(self.insets.left, self.insets.top, self.frame.size.width - self.insets.left - self.insets.right, self.frame.size.height - self.insets.top - self.insets.bottom);
}

- (void) setInsets:(UIEdgeInsets)insets
{
    _insets = insets;
    //we need to re-layout the subviews as the insets have changed
    [self layoutSubviews];
}

@end

关于cocoa-touch - UINavigationController:将通用填充/边距应用于所有弹出 View Controller 的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4547140/

有关cocoa-touch - UINavigationController:将通用填充/边距应用于所有弹出 View Controller 的 View的更多相关文章

随机推荐