ScrollViewの中に、複数のSubviewをframeで配置したい場合もあると思います。配置したいViewの数や、それぞれの高さが可変であるときなどはConstraintで指定するよりもframeで座標指定したほうがプログラミングしやすいこともあるでしょう。AutoLayoutとの兼ね合いからframeで配置する場合、気をつけないとうまく表示されません。

新たにSubviewを配置するとき

  • SubviewのtranslatesAutoresizingMaskIntoConstraintsをNOにする
  • UIScrollView#addSubviewで配置
  • UIScrollView#contentSizeを決定
  • frameの設定は必ずlayoutSubviewsで行う。また[super layoutSubviews]の後で行うこと

このような順番でプログラミングするとうまくいくはずです。

AutoLayout上ではframe設定を任意の場所で行っても無効になることがあります。確実に有効にするためにはlayoutSubviewsの中で行います。以下はその例です。

selfはUIScrollViewとする。

- (void)addTagView:(UIView *)tagView {
    [self addSubview:tagView];
    [_tagViews addObject:tagView];
    self.contentSize = [何らかの方法で求める];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    for (UIView *tagView in _tagViews) {
       tagView.frame = [何らかの方法で求める];
    }
}