あらゆる種類のUIViewの表示領域を単純にマスクする方法を知りたいです。私がこれまで読んだすべての答え/チュートリアルは、画像、グラデーション、または丸い角の作成によるマスキングについて説明しています。
例:境界(0、0、100、100)を持つUIViewがあり、マスクを使用してビューの右半分を切り取ります。したがって、マスクフレームは(0、0、50、100)になります。
これを簡単に行う方法はありますか? drawrectメソッドをオーバーライドしたくないのは、これはどのUIViewにも適用できるはずだからです。
私はこれを試しましたが、ビュー全体が見えなくなります。
CGRect mask = CGRectMake(0, 0, 50, 100);
UIView *maskView = [[UIView alloc] initWithFrame:mask];
viewToMask.layer.mask = maskView.layer;
MSKからのリンクのおかげで、これがうまくいった方法です。
// Create a mask layer and the frame to determine what will be visible in the view.
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGRect maskRect = CGRectMake(0, 0, 50, 100);
// Create a path with the rectangle in it.
CGPathRef path = CGPathCreateWithRect(maskRect, NULL);
// Set the path to the mask layer.
maskLayer.path = path;
// Release the path since it's not covered by ARC.
CGPathRelease(path);
// Set the mask of the view.
viewToMask.layer.mask = maskLayer;
マスクはまったく必要ありません。ちょうど小さいフレームでラッパービューに入れて、 clipsToBounds を設定します。
wrapper.clipsToBounds = YES;
回答ありがとうございます。
誰かがSOでこの質問に対して適切な答えを見つけられない場合、私がちょうどやったように、私はSwift 2.2 masking
/clipping
UIView
とCGRect
/UIBezierPath
の場合:
https://Gist.github.com/Flar49/7e977e81f1d2827f5fcd5c6c6a3c3d94
extension UIView {
func mask(withRect rect: CGRect, inverse: Bool = false) {
let path = UIBezierPath(rect: rect)
let maskLayer = CAShapeLayer()
if inverse {
path.append(UIBezierPath(rect: self.bounds))
maskLayer.fillRule = kCAFillRuleEvenOdd
}
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
}
func mask(withPath path: UIBezierPath, inverse: Bool = false) {
let path = path
let maskLayer = CAShapeLayer()
if inverse {
path.append(UIBezierPath(rect: self.bounds))
maskLayer.fillRule = kCAFillRuleEvenOdd
}
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
}
}
使用法:
let viewSize = targetView.bounds.size
let rect = CGRect(x: 20, y: 20, width: viewSize.width - 20*2, height: viewSize.height - 20*2)
// Cuts rectangle inside view, leaving 20pt borders around
targetView.mask(withRect: rect, inverse: true)
// Cuts 20pt borders around the view, keeping part inside rect intact
targetView.mask(withRect: rect)
将来誰かを救うことを願っています:)
Swift ViewController、受け入れられた答えに基づいた非常に簡単な例:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let redView = UIView(frame: view.bounds)
view.addSubview(redView)
view.backgroundColor = UIColor.greenColor()
redView.backgroundColor = UIColor.redColor()
mask(redView, maskRect: CGRect(x: 50, y: 50, width: 50, height: 50))
}
func mask(viewToMask: UIView, maskRect: CGRect) {
let maskLayer = CAShapeLayer()
let path = CGPathCreateWithRect(maskRect, nil)
maskLayer.path = path
// Set the mask of the view.
viewToMask.layer.mask = maskLayer;
}
}
出力
alpha channelのオプションレイヤーは、レイヤーの背景と、フィルター処理された背景でレイヤーのコンテンツを合成した結果の間で選択するためのマスクとして使用されます。
@property(retain)CALayer * mask
必要な処理を行う正しい方法は、マスクするレイヤーと同じmaskView
と同じフレーム(0、0、100、100)のviewToMask
を作成することです。次に、非表示にするパスにclearColorを設定する必要があります(これにより、パスに対するビューの対話がブロックされるため、ビューの階層に注意してください)。
Swift 5、@ Dan Rosenstarkに感謝
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let red = UIView(frame: view.bounds)
view.addSubview(red)
view.backgroundColor = UIColor.cyan
red.backgroundColor = UIColor.red
red.mask(CGRect(x: 50, y: 50, width: 50, height: 50))
}
}
extension UIView{
func mask(_ rect: CGRect){
let mask = CAShapeLayer()
let path = CGPath(rect: rect, transform: nil)
mask.path = path
// Set the mask of the view.
layer.mask = mask
}
}