我有一个 UINavigationController,我希望弹出到堆栈上的每个 View Controller 的 View 都具有共同的填充/边距(例如,所有边均为 25 像素)。实现此目标的最佳方法是什么?
我最初认为我可以实现 UINavigationControllerDelegate 并在 navigationController:didShowViewController:animated 或 navigationController:willShowViewController:animated 方法中,只需更改即将显示的 View Controller 的框架。但这似乎没有效果。
我试图在 View Controller 的 viewDidAppear 和 viewWillAppear 方法中做同样的事情,但这也没有用。理想情况下,无论如何我都不想在 Controller 中放置任何逻辑,因为它们可能并不总是在导航 Controller 中使用。
我还没有尝试过的最后一个想法是创建一个“包装器”UIViewController,它实际上会被推送到这个堆栈上。此包装器会将真实 View Controller 的 View 添加为 subview ,并带有可提供所需边距的框架。这里的缺点是我需要子类化 UINavigationController 并覆盖 pushViewController:animated,包装器将在其中被初始化和推送。 Apple 的文档表明 UINavigationController 不应该被子类化。
提前致谢。
最佳答案
我通过在 UIViewController 的 view 而不是 UIViewController 周围放置一个“包装器”UIView 来解决这个问题> 本身。然后,包装器 View 通过在 layoutSubviews 方法中设置 subview 的框架来填充 subview 。
为方便起见,我附上了我使用的代码。要使用,请将 UINavigationController 替换为 PaddedNavigationController,并设置 PaddedNavigationController 的 insets 属性。
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/