20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

20
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
20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?