iMessage のようなテキスト入力ビュー - MessageComposerView (質問に関連) を提供するオープン ソース ライブラリに取り組んでいます。ビューは のようにキーボードに固定され、inputAccessoryView
テキストと共に拡大しますが、キーボードが消えても消えません。
私は最近、ビューがinitWithFrame
. 基本的に、ビューが を介してインスタンス化された場合に UIDeviceOrientationDidChangeNotification 通知がキャッチされた時点initWithFrame
で、UIInterfaceOrientation とフレームはまだ更新されていません。インスタンス化する両方の方法を次に示します。
loadNibNamed
:
self.messageComposerView = [[NSBundle mainBundle] loadNibNamed:@"MessageComposerView" owner:nil options:nil][0];
self.messageComposerView.frame = CGRectMake(0,
self.view.frame.size.height - self.messageComposerView.frame.size.height,
self.messageComposerView.frame.size.width,
self.messageComposerView.frame.size.height);
initWithFrame
:
self.messageComposerView = [[MessageComposerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-54, 320, 54)];
経由で初期化しloadNibNamed
、横向きに回転すると、UIDeviceOrientationDidChangeNotification
通知を受信すると:
UIDeviceOrientation
= [[通知オブジェクト] 方向] = UIInterfaceOrientationLandscapeLeftUIInterfaceOrientation
= [UIApplication sharedApplication].statusBarOrientation = UIDeviceOrientationLandscapeRightself.frame.size
= (幅=480、高さ=90)
ここで注意すべき重要な点は、インターフェイスとデバイスの向きの両方が横向きであり、幅が既に横向きの幅に変更されていることです (iPhone 6.1 シミュレーターでのテスト)。同じテストを実行しますが、次を使用しinitWithFrame
ます。
UIDeviceOrientation
= [[通知オブジェクト] 方向] = UIDeviceOrientationLandscapeRightUIInterfaceOrientation
= [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortraitself.frame.size
= (幅=320、高さ=54)
今回は、インターフェイスの向きが縦のままで、フレームの幅が横幅に変わっていないことに注意してください。メソッドにブレークポイントを設定するsetFrame:(CGRect)frame
と、UIDeviceOrientationDidChangeNotification がキャッチされて処理された後に、フレームが横向きフレームに設定されていることがわかります。
両方の init メソッドのセットアップはほぼ同じです。
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.frame = frame;
self.sendButton = [[UIButton alloc] initWithFrame:CGRectZero];
self.messageTextView = [[UITextView alloc] initWithFrame:CGRectZero];
[self setup];
[self addSubview:self.sendButton];
[self addSubview:self.messageTextView];
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
[self setup];
}
setup
必要なビューの微調整を行うと:
- (void)setup {
self.backgroundColor = [UIColor lightGrayColor];
self.autoresizesSubviews = YES;
self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
self.userInteractionEnabled = YES;
self.multipleTouchEnabled = NO;
CGRect sendButtonFrame = self.bounds;
sendButtonFrame.size.width = 50;
sendButtonFrame.size.height = 34;
sendButtonFrame.origin.x = self.frame.size.width - kComposerBackgroundRightPadding - sendButtonFrame.size.width;
sendButtonFrame.origin.y = kComposerBackgroundRightPadding;
self.sendButton.frame = sendButtonFrame;
self.sendButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
self.sendButton.layer.cornerRadius = 5;
[self.sendButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.sendButton setTitleColor:[UIColor colorWithRed:210/255.0 green:210/255.0 blue:210/255.0 alpha:1.0] forState:UIControlStateHighlighted];
[self.sendButton setTitleColor:[UIColor grayColor] forState:UIControlStateSelected];
[self.sendButton setBackgroundColor:[UIColor orangeColor]];
[self.sendButton setTitle:@"Send" forState:UIControlStateNormal];
self.sendButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
CGRect messageTextViewFrame = self.bounds;
messageTextViewFrame.origin.x = kComposerBackgroundLeftPadding;
messageTextViewFrame.origin.y = kComposerBackgroundTopPadding;
messageTextViewFrame.size.width = self.frame.size.width - kComposerBackgroundLeftPadding - kComposerTextViewButtonBetweenPadding - sendButtonFrame.size.width - kComposerBackgroundRightPadding;
messageTextViewFrame.size.height = 34;
self.messageTextView.frame = messageTextViewFrame;
self.messageTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
self.messageTextView.showsHorizontalScrollIndicator = NO;
self.messageTextView.layer.cornerRadius = 5;
self.messageTextView.font = [UIFont systemFontOfSize:14];
self.messageTextView.delegate = self;
[self addNotifications];
[self resizeTextViewForText:@"" animated:NO];
}
だから私の質問は、なぜ私のカスタムUIView init viainitWithFrame
がまだ縦長のフレームとインターフェースの向きと、UIDeviceOrientationDidChangeNotificationが受信された時間を持っているのですか? この通知を使用してフレームの調整を行い、幅が既に横幅に更新されている必要があります。
XIBのどこかに埋もれているが、それを見つけることができない、プログラムによるセットアップに欠けているある種の自動回転プロパティがあることを願っています。解決策を見つけることなく、おそらく十数回のUIDeviceOrientationDidChangeNotification
スタックオーバーフローの投稿を経験しました。