【Swift】ScrollView内のボタンが押せなくなった時の対処法

ScrollViewのcontentView下部(スクロールしないと現れない部分)にボタンを設置した時に、ボタンがクリック出来ず試行錯誤したので、その時の対処法を書いていきます。

1. 問題の再現

まずは問題を再現していきましょう。

storyboardとauto layoutを使っていて、似たような設定であれば同じ問題の可能性が高いと思います。

1-1. Storyboardの設定

以下storyboardのview hierarchyです。

ScrollViewの中にUIViewを追加し、それぞれ違う位置にボタンを配置しています。

問題を再現するために、iPhone6のシミュレーターを使います。

 

うまく再現するには、画面が表示された際にファーストビューでは青いボタンのみが視認出来る状態にしてください。

 

ScrollViewとScrollView直下のUIViewのlayoutsconstraintは下記のようになっています。

1. scrollviewのlayouts constraint

 

四辺をSafe Areaに引っ付けています。

 

2. scrollviewcontentのlayouts constraint

 

四辺をScrollView(Superview)に引っ付けて、さらにAlign XとYをScrollView(Superview)に対して0にしています。

 

1-2. UIViewControllerの設定

次に、ボタンをタップしたらわかるようにUIViewControllerにIBActionを追加します。

さらに、UIViewControllerのSubView(scrollViewなど)がレイアウトされたタイミングでscrollViewのスクロール領域をscrollViewContentと同じ高さにします。

 

それでは実際にビルドして試してみましょう。

 

 

青いボタンをタップしたらちゃんとアラートが出ますが、赤いボタンはタップしても何も起きません。

 

2.ボタンが押せない理由

結論から言いますと、画面をスクロールした際に、赤いボタンがscrollContentView内に収まらなくなってしまっているため、タップ出来ない状態となっています。

 

ボタンなどがタップできなくなった時に、個人的に私がまず確認することは以下の2つです。

  1. isUserInterationEnabledがfalseになっていないか
  2. ViewHierarchyを見てみて、別の要素が覆いかぶさっていないかなどのチェック

 

①isUserInterationEnabledがfalseになっていないか

何かの間違いでチェックを外していないか、コードで明示的に指定していないか確認します。

 

②View Hierarchyを見てみて、別の要素が覆いかぶさっていないかなどのチェック

XcodeにはView Debuggerというすごく便利な機能がついてます。

ビルド後にコンソールウィンドウの上にある、下記のアイコンを押すことで、絵画されているViewを階層的に見ることが出来ます。

View Debugger Icon:

 

実際のスクリーンショットが以下です。

 

別アングル:

上記のように、赤いボタンがscrollContentViewから外れてしまっているのがわかります。

それではこれを修正していきましょう。

3.対処法

色々調べたり、弄ったりしてたらalign contents to y axisが原因になっているようです。スクロールすると、autolayoutが勝手にリサイズしてy axisが0で固定されるのが原因なっているのではないかと思います(的外れなことを言ってたらすみません)。

 

色々試した結果、以下の手順でボタンをcontentView内に収めることができました。

  1. scrollViewContentのalign center Y to SuperviewのPriorityを1000(Required)から750(High)に下げる
  2. scrollViewContentのtranslatesAutoresizingMaskIntoConstraints = trueにする
  3. scrollViewContentのFrameを明示的に作り直す

align center Yの優先度を下げ、scrollViewContentのtranslatesAutoresizingMaskIntoConstraintsをtrueにします。以下、Swift Documentationからの抜粋です:

If this property’s value is true, the system creates a set of constraints that duplicate the behavior specified by the view’s autoresizing mask. This also lets you modify the view’s size and location using the view’s frame, bounds, or center properties, allowing you to create a static, frame-based layout within Auto Layout

これをtrueにすることによって、Viewのframeなどの修正を行うことが出来るようです。

ただし、その分layout constraintsを害さないように設計しないといけません。

それでは、以下の手順を行なっていきましょう:

  1. scrollViewContentのalign center Y to SuperviewのPriorityを1000(Required)から750(High)に下げる
  2. scrollViewContentのtranslatesAutoresizingMaskIntoConstraints = trueにする
  3. scrollViewContentのFrameを明示的に作り直す

 

ちゃんと赤いボタンもタップ出来るようになりました!

最終的にViewControllerは以下のようになっています。

 

以上、ScrollView内のボタンが押せなくなった時の対処法でした。

一つの参考例として読んでいただければ幸いです。

 

参考URL