UIViewController
の代わりにUIViewController
のview
の周りに "ラッパー" UIView
を入れて解決しました。ラッパービューは、layoutSubviews
メソッドのサブビューのフレームを設定することによって、サブビューを埋め込みます。
私は便宜的に使用したコードを添付しました。使用するには、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
は、上記の "最後のアイデア" を実装しようとしましたが、暗礁に乗り上げます。表示されているビューコントローラは実際には別のビューコントローラによって「ラップ」されており、ラッパーは実際にスタックにプッシュされているため、表示されているビューコントローラのnavigationControllerプロパティは 'nil'です。これは、別のView Controllerを上に押し込むためにNavigation Controllerへのハンドルを取得できないことを意味します。 –
別のデータポイント: 'navigationController:didShowViewController:animated'のビューコントローラのビューのフレームを実際に変更すると、実際には動作しますが、ビューコントローラは最初に元のフレームに表示され、事実の後にサイズが変更されます。しかし、「navigationController:willShowViewController:animated」のフレームを変更しても効果はありません。 –