ios 違い XIBからプログラムでカスタムUIViewのサイズを変更する




xib swift4 (3)

xibをコンテンツビューに追加するときに自動レイアウトを使用しないことが主な問題であると思います。
initメソッドにサブビューを追加した後、xibのビューを渡してそのメソッドを呼び出してください。

- (void) stretchToSuperView:(UIView*) view {
    view.translatesAutoresizingMaskIntoConstraints = NO;
    NSDictionary *bindings = NSDictionaryOfVariableBindings(view);
    NSString *formatTemplate = @"%@:|[view]|";
    for (NSString * axis in @[@"H",@"V"]) {
        NSString * format = [NSString stringWithFormat:formatTemplate,axis];
        NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:bindings];
        [view.superview addConstraints:constraints];
    }

}

[編集]
セットアップコードは次のようになります。

- (void)setup {
    if (self.subviews.count == 0) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil];
        self.bounds = self.view.bounds;
        [self addSubview:self.view];
        [self stretchToSuperView:self.view];
    }
}

ストレッチビューの内側にview.translatesAutoresizingMaskIntoConstraints = NO;を追加したことに注意してくださいview.translatesAutoresizingMaskIntoConstraints = NO;
[編集2]
私は要求に応じて私の答えを詳しく述べるようにします。 自動レイアウトを使用して、制約を設定せずにビューを追加すると、自動レイアウトマスクは自動的に自動サイズ変更マスクを制約に変換します。デフォルトのプロパティはUIViewAutoresizingNone 、自動サイズ変更は行われません。
あなたのXIBビューは、制約なしに、そして自動サイズ変更の可能性なしに、その元のサイズを維持することなく、その親に追加されました。 自分のビューに合わせて自分のビューのサイズを変更したいので、2つの選択肢がありました。

  • xibビューの自動サイズ変更マスクを柔軟な幅と高さに変更しますが、親サイズと一致する必要があります。そうしないと、フルカバーが表示されません。
  • 親の変更に合わせて変更するために2つのビューを制約する制約をいくつか追加します。 そして、あなたは、XIBビューとその親ビューの間で、後続/先行と上部/ボットンの間のスペースが0であると言うことを達成します。あなたがそれらの境界に接着剤を置いているようです。 これを行うには、自動翻訳のサイズ変更マスクをNOに制限するように設定する必要があります。そうしないと、ログに投稿したときに競合が発生する可能性があります。

後で行うのは、スーパービューにビュー(XIBビューをホストする)に制約を追加することですが、XIBとその親の間に制約はありませんでした。したがって、自動レイアウトはXIBビューのサイズ変更方法を知りません。
ビュー階層内の各ビューには独自の制約があります。
これがよりよく理解するのに役立つことを願っています。

次のような問題がXIBます。カスタムUIViewクラスとそのレイアウトをXIBファイルに作成しました。 XIBでのカスタムビューのサイズが150 x 50であるとしましょうsizeClasses (wAny hAny)とAutoLayoutを有効にしsizeClasses 。 Simulated Metricsでは、 Size = FreeformStatus Bar = Noneother = Inferredすべてother = Inferred

私のカスタムUIViewクラスのコードは次のようになります。

#import "CustomView.h"

@implementation CustomView

#pragma mark - Object lifecycle

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];

    if (self) {
        [self setup];
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];

    if (self) {
        [self setup];
    }

    return self;
}

#pragma mark - Private & helper methods

- (void)setup {
    if (self.subviews.count == 0) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil];
        self.bounds = self.view.bounds;
        [self addSubview:self.view];
    }
}

@end

このカスタムUIViewを追加したいUIViewControllerでは、 UIViewControllerを追加したい場所にダミーのUIView(Interface Builderで設定したサイズ)を作成し、自分のCustomView コンテナビューの範囲に収まるようにします

私はこのようにしようとしています:

_vCustomView = [[CustomView alloc] init];
_vCustomView.translatesAutoresizingMaskIntoConstraints = NO;
[_vContainer addSubview:_vCustomView];

[_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]];
[_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]];
[_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]];

しかし、運が悪い。 私のカスタムUIViewをそれに追加したとき、私のコンテナービューが300 x 100だとしましょう、 私のカスタムビューはまだ150 x 50です。

私はコンテナビューなしで作業しようとしました - 私のUIViewController self.viewに直接私のカスタムUIViewオブジェクトを追加して、それの幅と高さを設定するために:

  • autoLayout制約
  • 私のカスタムUIView初期化するときinitWithFrameを使うことによって

しかし、再び - 運はありません。 カスタムビューは常に150 x 50です。

XIBで作成したカスタムUIViewプログラムで追加し、 autoLayout制約を使用してサイズを変更するにはどうすればよいですか。

事前に感謝します。

編集#1:私のCustomViewでAndreaのコードを実行しようとしたときに私が得るエラー

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x17489b760 V:[UIView:0x17418d820(91)]>",
    "<NSLayoutConstraint:0x170c9bf80 V:|-(0)-[CustomView:0x1741da7c0]   (Names: '|':CustomView:0x1741da8b0 )>",
    "<NSLayoutConstraint:0x170c9bfd0 V:[CustomView:0x1741da7c0]-(0)-|   (Names: '|':CustomView:0x1741da8b0 )>",
    "<NSLayoutConstraint:0x170c9be90 V:|-(0)-[CustomView:0x1741da8b0]   (Names: '|':UIView:0x17418d820 )>",
    "<NSLayoutConstraint:0x170c9bee0 CustomView:0x1741da8b0.bottom == UIView:0x17418d820.bottom>",
    "<NSAutoresizingMaskLayoutConstraint:0x170c9dba0 h=--& v=--& CustomView:0x1741da7c0.midY == + 25.0>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170c9bfd0 V:[CustomView:0x1741da7c0]-(0)-|   (Names: '|':CustomView:0x1741da8b0 )>

編集#2:それはうまくいきます!

@Andreaが追加された後:

view.translatesAutoresizingMaskIntoConstraints = NO;

彼の中で:

- (void) stretchToSuperView:(UIView*) view;

方法、すべてが私の期待通りに動作します。

@Andreaに感謝します。


スーパービューに拡大するSwift 4.0の機能:

コードスニペット:

static public func stretchToSuperView(view:UIView)
    {
        view.translatesAutoresizingMaskIntoConstraints = false
        var d = Dictionary<String,UIView>()
        d["view"] = view
        for axis in ["H","V"] {
            let format = "\(axis):|[view]|"
            let constraints = NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(rawValue: 0), metrics: [:], views: d)
            view.superview?.addConstraints(constraints)
        }
    }

注意:サブビューとして引数を付けて関数を呼び出すだけです。

これは私がswift 4.0の.xib resing問題を解決するのを助けます。


あなたのコードでは、次のようなものがあるはずです。

まず、viewControllerまたはCustomViewいずれかで、変更したい幅の制約へのIBOutlet(制約値を計算するためのロジックがどこにあるかわかりません)。

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *widthConstraint;

そして、このメソッドで定数値を更新したい場合は、次のようにします。

-(void)updateWidth {
    [self.widthConstraint setConstant:newConstant];
    [self.view layoutIfNeeded]; // self.view must be an ancestor of the view

    //If you need the changes animated, call layoutIfNeeded in an animation block
}

これがあなたのために働くことを願っています。 がんばろう!





autolayout