LoginSignup
19
21

More than 5 years have passed since last update.

UIViewのサブクラスによってmasksToBoundsの初期値が異なる

Last updated at Posted at 2015-12-19

UIViewのサブクラスはCALayerクラスをもっています。そんなCALayerのmasksToBoundsのプロパティの初期値がUIViewのサブクラスによって異なっていたので共有したいと思います。

masksToBounds

まず、masksToBoundsプロパティの説明ですが、CALayer Class Referenceによると下記のように記述してあります。

When the value of this property is true, Core Animation creates an implicit clipping mask that matches the bounds of the layer and includes any corner radius effects. If a value for the mask property is also specified, the two masks are multiplied to get the final mask value.

The default value of this property is false.

CALayer Class Reference参照

つまりmasksToBoundsがtrueの場合はコンテンツのサブレイヤの境界矩形外に描画処理はされないようですね。CALayer Class Referenceによると初期値はfalseとされています。

使用例

        let view  = UIView(frame: CGRectMake(0, 0, 200, 50))
        view.backgroundColor = UIColor.lightGrayColor()
        view.layer.masksToBounds = false
        self.view.addSubview(view)

        let label = UILabel(frame: CGRectMake(0, 0, 300, 50))
        label.text = "masksToBounds Test by Shohei"
        self.view.addSubview(label)

masksToBoundsがfalseの状態だとUILabelがUIViewをはみだしてもしっかり描画されていますね。

スクリーンショット 2015-12-19 15.51.15.png

この状態でmasksToBoundsをtrueにしてあげると、下の図のようにUIViewの境界矩形外は描画されなくなります。

スクリーンショット 2015-12-19 15.50.59.png

つまりmasksToBoundsをtrueの状態だと影の描画などもされなくなるんですね。

masksToBoundsの初期値の違いについて

CALayer Class ReferenceではmasksToBoundsの初期値はfalseとされていましたが、UIViewのサブクラスによって初期値は異なるようです。

ウィンドウ系

        let window = UIWindow()//デバイスの画面上の最下層のビュー
        print(window.layer.masksToBounds)// ->false

コンテンツ表示系

        let label = UILabel()//テキスト表示
        print(label.layer.masksToBounds)// ->false

        let textView = UITextView()//テキストの表示・編集
        print(textView.layer.masksToBounds)// ->true

        let imageView = UIImageView()//画像表示
        print(imageView.layer.masksToBounds)// ->false

        let scrollView = UIScrollView()//スクロール可能なビュー
        print(scrollView.layer.masksToBounds)// ->true

        let webView = UIWebView()//ウェブコンテンツ表示
        print(webView.layer.masksToBounds)// ->false

        let progressView = UIProgressView()//進捗の表示
        print(progressView.layer.masksToBounds)// ->false

        let activityIndicatorView = UIActivityIndicatorView()//処理中を示すビュー
        print(activityIndicatorView.layer.masksToBounds)// ->false

        let actionSheet = UIActionSheet()//アクション表示(iOS8.3からはUIAlertController推奨)
        print(actionSheet.layer.masksToBounds)// ->false

        let alertView = UIAlertView()//アラート表示のためのポップアップ
        print(alertView.layer.masksToBounds)// ->false

        let pickerView = UIPickerView()//選択肢の表示と選択
        print(pickerView.layer.masksToBounds)// ->true

データコレクション表示系

        let tableView = UITableView()//縦方向にセルを表示
        print(tableView.layer.masksToBounds)// ->true

        let collectionView = UICollectionView()//任意のレイアウトでセル表示
        print(collectionView.layer.masksToBounds)// ->true

UIコントロール系

        let control = UIControl()//UIコントロール共通のスーパークラス
        print(control.layer.masksToBounds)// ->false

        let button = UIButton()//ボタン
        print(button.layer.masksToBounds)// ->false

        let textField = UITextField()//テキストの表示・編集
        print(textField.layer.masksToBounds)// ->true

        let switch = UISwitch()//オン・オフスイッチ
        print(switch.layer.masksToBounds)// ->false

        let segmentedControl = UISegmentedControl()//セグメントによる選択肢表示
        print(segmentedControl.layer.masksToBounds)// ->false

        let stepper = UIStepper()//段階式値の加算・減算
        print(stepper.layer.masksToBounds)// ->false

        let slider = UISlider()//スライダー
        print(slider.layer.masksToBounds)// ->false

        let datePicker = UIDatePicker()//日付・時刻のピッカー
        print(datePicker.layer.masksToBounds)// ->false

        let refreshControl = UIRefreshControl()//更新コントロール
        print(refreshControl.layer.masksToBounds)// ->false

        let pageControl = UIPageControl()//ページ表示
        print(pageControl.layer.masksToBounds)// ->false

タブバー系

        let tabBar = UITabBar()//タブバー
        print(tabBar.layer.masksToBounds)// ->false

        let navigationBar = UINavigationBar()//ナビゲーションバー
        print(navigationBar.layer.masksToBounds)// ->false

        let toolbar = UIToolbar()//ツールバー
        print(toolbar.layer.masksToBounds)// ->false

        let searchBar = UISearchBar()//検索バー
        print(searchBar.layer.masksToBounds)// ->false

masksToBoundsの初期値が異なるUIViewサブクラス

  • UITextView
  • UIScrollView
  • UIPickerView
  • UITableView
  • UICollectionView
  • UITextField

これらのクラスはmasksToBoundsの初期値がtrueになっていますね。
よってサブビューのコンテンツをはみだして表示したい場合や影の描画をする場合はmasksToBoundsをfalseにする必要があります

最後に

masksToBoundsの初期値がtrueになってるということは、境界矩形外の描画は推奨されていないと思いますが、クラスによる初期値の違いは理解しておく必要があると思います。
他にもプロパティの初期値がクラスによって異なる場合はあると思いますので、知っておくとバグの早期発見などにも役立つと思います。

19
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
21