1

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= [[通知オブジェクト] 方向] = UIInterfaceOrientationLandscapeLeft
  • UIInterfaceOrientation= [UIApplication sharedApplication].statusBarOrientation = UIDeviceOrientationLandscapeRight
  • self.frame.size= (幅=480、高さ=90)

ここで注意すべき重要な点は、インターフェイスとデバイスの向きの両方が横向きであり、幅が既に横向きの幅に変更されていることです (iPhone 6.1 シミュレーターでのテスト)。同じテストを実行しますが、次を使用しinitWithFrameます。

  • UIDeviceOrientation= [[通知オブジェクト] 方向] = UIDeviceOrientationLandscapeRight
  • UIInterfaceOrientation= [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait
  • self.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スタックオーバーフローの投稿を経験しました。

4

1 に答える 1