Mask UIView with another UIView










3














Yes this question has been asked before, the solutions did not work or had different applications.



It is the most basic setup. I have two rectangular UIViews, red and blue.
I would like the blue square to cut into the red square, so the red square looks like an "L"



enter image description here



import Foundation
import UIKit

class TestController: UIViewController
override func viewDidLoad()
view.backgroundColor = .gray
view.addSubview(viewA)
view.addSubview(maskView)

viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
viewA.translatesAutoresizingMaskIntoConstraints = false

maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
maskView.translatesAutoresizingMaskIntoConstraints = false

// Things which don't work
//viewA.mask = maskView // both views disappear
//viewA.layer.mask = maskView.layer // both views disappear
//viewA.layer.addSublayer(maskView.layer) // hides mask view


var viewA: UIView =
let view = UIView()
view.backgroundColor = .red
view.layer.masksToBounds = true
return view
()

var maskView: UIView =
let view = UIView()
view.backgroundColor = .blue
return view
()



This is the result I am expecting: (done in Photoshop)



enter image description here










share|improve this question




























    3














    Yes this question has been asked before, the solutions did not work or had different applications.



    It is the most basic setup. I have two rectangular UIViews, red and blue.
    I would like the blue square to cut into the red square, so the red square looks like an "L"



    enter image description here



    import Foundation
    import UIKit

    class TestController: UIViewController
    override func viewDidLoad()
    view.backgroundColor = .gray
    view.addSubview(viewA)
    view.addSubview(maskView)

    viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
    viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
    viewA.translatesAutoresizingMaskIntoConstraints = false

    maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
    maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
    maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
    maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    maskView.translatesAutoresizingMaskIntoConstraints = false

    // Things which don't work
    //viewA.mask = maskView // both views disappear
    //viewA.layer.mask = maskView.layer // both views disappear
    //viewA.layer.addSublayer(maskView.layer) // hides mask view


    var viewA: UIView =
    let view = UIView()
    view.backgroundColor = .red
    view.layer.masksToBounds = true
    return view
    ()

    var maskView: UIView =
    let view = UIView()
    view.backgroundColor = .blue
    return view
    ()



    This is the result I am expecting: (done in Photoshop)



    enter image description here










    share|improve this question


























      3












      3








      3







      Yes this question has been asked before, the solutions did not work or had different applications.



      It is the most basic setup. I have two rectangular UIViews, red and blue.
      I would like the blue square to cut into the red square, so the red square looks like an "L"



      enter image description here



      import Foundation
      import UIKit

      class TestController: UIViewController
      override func viewDidLoad()
      view.backgroundColor = .gray
      view.addSubview(viewA)
      view.addSubview(maskView)

      viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
      viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
      viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
      viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
      viewA.translatesAutoresizingMaskIntoConstraints = false

      maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
      maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
      maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
      maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
      maskView.translatesAutoresizingMaskIntoConstraints = false

      // Things which don't work
      //viewA.mask = maskView // both views disappear
      //viewA.layer.mask = maskView.layer // both views disappear
      //viewA.layer.addSublayer(maskView.layer) // hides mask view


      var viewA: UIView =
      let view = UIView()
      view.backgroundColor = .red
      view.layer.masksToBounds = true
      return view
      ()

      var maskView: UIView =
      let view = UIView()
      view.backgroundColor = .blue
      return view
      ()



      This is the result I am expecting: (done in Photoshop)



      enter image description here










      share|improve this question















      Yes this question has been asked before, the solutions did not work or had different applications.



      It is the most basic setup. I have two rectangular UIViews, red and blue.
      I would like the blue square to cut into the red square, so the red square looks like an "L"



      enter image description here



      import Foundation
      import UIKit

      class TestController: UIViewController
      override func viewDidLoad()
      view.backgroundColor = .gray
      view.addSubview(viewA)
      view.addSubview(maskView)

      viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
      viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
      viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
      viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
      viewA.translatesAutoresizingMaskIntoConstraints = false

      maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
      maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
      maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
      maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
      maskView.translatesAutoresizingMaskIntoConstraints = false

      // Things which don't work
      //viewA.mask = maskView // both views disappear
      //viewA.layer.mask = maskView.layer // both views disappear
      //viewA.layer.addSublayer(maskView.layer) // hides mask view


      var viewA: UIView =
      let view = UIView()
      view.backgroundColor = .red
      view.layer.masksToBounds = true
      return view
      ()

      var maskView: UIView =
      let view = UIView()
      view.backgroundColor = .blue
      return view
      ()



      This is the result I am expecting: (done in Photoshop)



      enter image description here







      ios swift mask






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 18:05

























      asked Nov 11 at 1:05









      arvidurs

      79521025




      79521025






















          1 Answer
          1






          active

          oldest

          votes


















          0














          As there is no magic way to mask the way in iOS, I present here a simple way to achieve this.



          Don't forget to pan the clear area, If leaving the red square, it will become a blue square.



          It's not hard to modify the subclass of UIViews for your own purpose, especially views.



           import UIKit

          class TestController: UIViewController

          override func viewDidLoad()
          view.backgroundColor = .gray
          view.addSubview(viewA)
          view.addSubview(maskView)
          maskView.maskedView = viewA
          viewA.activeMask = maskView
          viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
          viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.translatesAutoresizingMaskIntoConstraints = false
          maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
          maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
          maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.translatesAutoresizingMaskIntoConstraints = false


          var viewA: MyUIView =
          let view = MyUIView()
          view.backgroundColor = .clear
          view.layer.masksToBounds = true
          return view
          ()


          var maskView: ActiveMaskView =
          let view = ActiveMaskView()
          view.backgroundColor = .clear
          return view
          ()




          class ActiveMaskView: UIView
          override func didMoveToSuperview()
          super.didMoveToSuperview()
          let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(moveAround(_:)))
          self.addGestureRecognizer(panGesture)

          weak var maskedView : UIView?
          private var frameOrigin : CGPoint = CGPoint.zero

          @objc func moveAround(_ panGesture: UIPanGestureRecognizer)
          guard let superview = superview else return
          switch panGesture.state
          case .began:
          frameOrigin = frame.origin
          self.backgroundColor = UIColor.blue
          case .changed:
          let translation = panGesture.translation(in: superview)
          frame = CGRect.init(origin: CGPoint.init(x: frameOrigin.x + translation.x, y: frameOrigin.y + translation.y), size: frame.size)
          maskedView?.setNeedsDisplay()
          break
          case .ended:
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          case .cancelled:
          frame = CGRect.init(origin: frameOrigin , size: frame.size)
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          default:
          break;




          class MyUIView: UIView

          weak var activeMask: ActiveMaskView?

          override func draw(_ rect: CGRect)
          super.draw(rect)
          let ctx = UIGraphicsGetCurrentContext()
          ctx?.setFillColor(UIColor.red.cgColor)
          ctx?.fill(self.layer.bounds)
          ctx?.setBlendMode(.sourceOut)
          guard let activeMask = activeMask , let superview = superview else
          return

          let sc = frame.intersection(activeMask.frame)
          let interSection = superview.convert(sc, to: self)
          ctx?.fill(interSection )







          share|improve this answer




















          • hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
            – arvidurs
            Nov 13 at 16:51











          • It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
            – E.Coms
            Nov 13 at 17:24










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244941%2fmask-uiview-with-another-uiview%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          As there is no magic way to mask the way in iOS, I present here a simple way to achieve this.



          Don't forget to pan the clear area, If leaving the red square, it will become a blue square.



          It's not hard to modify the subclass of UIViews for your own purpose, especially views.



           import UIKit

          class TestController: UIViewController

          override func viewDidLoad()
          view.backgroundColor = .gray
          view.addSubview(viewA)
          view.addSubview(maskView)
          maskView.maskedView = viewA
          viewA.activeMask = maskView
          viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
          viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.translatesAutoresizingMaskIntoConstraints = false
          maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
          maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
          maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.translatesAutoresizingMaskIntoConstraints = false


          var viewA: MyUIView =
          let view = MyUIView()
          view.backgroundColor = .clear
          view.layer.masksToBounds = true
          return view
          ()


          var maskView: ActiveMaskView =
          let view = ActiveMaskView()
          view.backgroundColor = .clear
          return view
          ()




          class ActiveMaskView: UIView
          override func didMoveToSuperview()
          super.didMoveToSuperview()
          let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(moveAround(_:)))
          self.addGestureRecognizer(panGesture)

          weak var maskedView : UIView?
          private var frameOrigin : CGPoint = CGPoint.zero

          @objc func moveAround(_ panGesture: UIPanGestureRecognizer)
          guard let superview = superview else return
          switch panGesture.state
          case .began:
          frameOrigin = frame.origin
          self.backgroundColor = UIColor.blue
          case .changed:
          let translation = panGesture.translation(in: superview)
          frame = CGRect.init(origin: CGPoint.init(x: frameOrigin.x + translation.x, y: frameOrigin.y + translation.y), size: frame.size)
          maskedView?.setNeedsDisplay()
          break
          case .ended:
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          case .cancelled:
          frame = CGRect.init(origin: frameOrigin , size: frame.size)
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          default:
          break;




          class MyUIView: UIView

          weak var activeMask: ActiveMaskView?

          override func draw(_ rect: CGRect)
          super.draw(rect)
          let ctx = UIGraphicsGetCurrentContext()
          ctx?.setFillColor(UIColor.red.cgColor)
          ctx?.fill(self.layer.bounds)
          ctx?.setBlendMode(.sourceOut)
          guard let activeMask = activeMask , let superview = superview else
          return

          let sc = frame.intersection(activeMask.frame)
          let interSection = superview.convert(sc, to: self)
          ctx?.fill(interSection )







          share|improve this answer




















          • hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
            – arvidurs
            Nov 13 at 16:51











          • It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
            – E.Coms
            Nov 13 at 17:24















          0














          As there is no magic way to mask the way in iOS, I present here a simple way to achieve this.



          Don't forget to pan the clear area, If leaving the red square, it will become a blue square.



          It's not hard to modify the subclass of UIViews for your own purpose, especially views.



           import UIKit

          class TestController: UIViewController

          override func viewDidLoad()
          view.backgroundColor = .gray
          view.addSubview(viewA)
          view.addSubview(maskView)
          maskView.maskedView = viewA
          viewA.activeMask = maskView
          viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
          viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.translatesAutoresizingMaskIntoConstraints = false
          maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
          maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
          maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.translatesAutoresizingMaskIntoConstraints = false


          var viewA: MyUIView =
          let view = MyUIView()
          view.backgroundColor = .clear
          view.layer.masksToBounds = true
          return view
          ()


          var maskView: ActiveMaskView =
          let view = ActiveMaskView()
          view.backgroundColor = .clear
          return view
          ()




          class ActiveMaskView: UIView
          override func didMoveToSuperview()
          super.didMoveToSuperview()
          let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(moveAround(_:)))
          self.addGestureRecognizer(panGesture)

          weak var maskedView : UIView?
          private var frameOrigin : CGPoint = CGPoint.zero

          @objc func moveAround(_ panGesture: UIPanGestureRecognizer)
          guard let superview = superview else return
          switch panGesture.state
          case .began:
          frameOrigin = frame.origin
          self.backgroundColor = UIColor.blue
          case .changed:
          let translation = panGesture.translation(in: superview)
          frame = CGRect.init(origin: CGPoint.init(x: frameOrigin.x + translation.x, y: frameOrigin.y + translation.y), size: frame.size)
          maskedView?.setNeedsDisplay()
          break
          case .ended:
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          case .cancelled:
          frame = CGRect.init(origin: frameOrigin , size: frame.size)
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          default:
          break;




          class MyUIView: UIView

          weak var activeMask: ActiveMaskView?

          override func draw(_ rect: CGRect)
          super.draw(rect)
          let ctx = UIGraphicsGetCurrentContext()
          ctx?.setFillColor(UIColor.red.cgColor)
          ctx?.fill(self.layer.bounds)
          ctx?.setBlendMode(.sourceOut)
          guard let activeMask = activeMask , let superview = superview else
          return

          let sc = frame.intersection(activeMask.frame)
          let interSection = superview.convert(sc, to: self)
          ctx?.fill(interSection )







          share|improve this answer




















          • hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
            – arvidurs
            Nov 13 at 16:51











          • It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
            – E.Coms
            Nov 13 at 17:24













          0












          0








          0






          As there is no magic way to mask the way in iOS, I present here a simple way to achieve this.



          Don't forget to pan the clear area, If leaving the red square, it will become a blue square.



          It's not hard to modify the subclass of UIViews for your own purpose, especially views.



           import UIKit

          class TestController: UIViewController

          override func viewDidLoad()
          view.backgroundColor = .gray
          view.addSubview(viewA)
          view.addSubview(maskView)
          maskView.maskedView = viewA
          viewA.activeMask = maskView
          viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
          viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.translatesAutoresizingMaskIntoConstraints = false
          maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
          maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
          maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.translatesAutoresizingMaskIntoConstraints = false


          var viewA: MyUIView =
          let view = MyUIView()
          view.backgroundColor = .clear
          view.layer.masksToBounds = true
          return view
          ()


          var maskView: ActiveMaskView =
          let view = ActiveMaskView()
          view.backgroundColor = .clear
          return view
          ()




          class ActiveMaskView: UIView
          override func didMoveToSuperview()
          super.didMoveToSuperview()
          let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(moveAround(_:)))
          self.addGestureRecognizer(panGesture)

          weak var maskedView : UIView?
          private var frameOrigin : CGPoint = CGPoint.zero

          @objc func moveAround(_ panGesture: UIPanGestureRecognizer)
          guard let superview = superview else return
          switch panGesture.state
          case .began:
          frameOrigin = frame.origin
          self.backgroundColor = UIColor.blue
          case .changed:
          let translation = panGesture.translation(in: superview)
          frame = CGRect.init(origin: CGPoint.init(x: frameOrigin.x + translation.x, y: frameOrigin.y + translation.y), size: frame.size)
          maskedView?.setNeedsDisplay()
          break
          case .ended:
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          case .cancelled:
          frame = CGRect.init(origin: frameOrigin , size: frame.size)
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          default:
          break;




          class MyUIView: UIView

          weak var activeMask: ActiveMaskView?

          override func draw(_ rect: CGRect)
          super.draw(rect)
          let ctx = UIGraphicsGetCurrentContext()
          ctx?.setFillColor(UIColor.red.cgColor)
          ctx?.fill(self.layer.bounds)
          ctx?.setBlendMode(.sourceOut)
          guard let activeMask = activeMask , let superview = superview else
          return

          let sc = frame.intersection(activeMask.frame)
          let interSection = superview.convert(sc, to: self)
          ctx?.fill(interSection )







          share|improve this answer












          As there is no magic way to mask the way in iOS, I present here a simple way to achieve this.



          Don't forget to pan the clear area, If leaving the red square, it will become a blue square.



          It's not hard to modify the subclass of UIViews for your own purpose, especially views.



           import UIKit

          class TestController: UIViewController

          override func viewDidLoad()
          view.backgroundColor = .gray
          view.addSubview(viewA)
          view.addSubview(maskView)
          maskView.maskedView = viewA
          viewA.activeMask = maskView
          viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
          viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
          viewA.translatesAutoresizingMaskIntoConstraints = false
          maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
          maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
          maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
          maskView.translatesAutoresizingMaskIntoConstraints = false


          var viewA: MyUIView =
          let view = MyUIView()
          view.backgroundColor = .clear
          view.layer.masksToBounds = true
          return view
          ()


          var maskView: ActiveMaskView =
          let view = ActiveMaskView()
          view.backgroundColor = .clear
          return view
          ()




          class ActiveMaskView: UIView
          override func didMoveToSuperview()
          super.didMoveToSuperview()
          let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(moveAround(_:)))
          self.addGestureRecognizer(panGesture)

          weak var maskedView : UIView?
          private var frameOrigin : CGPoint = CGPoint.zero

          @objc func moveAround(_ panGesture: UIPanGestureRecognizer)
          guard let superview = superview else return
          switch panGesture.state
          case .began:
          frameOrigin = frame.origin
          self.backgroundColor = UIColor.blue
          case .changed:
          let translation = panGesture.translation(in: superview)
          frame = CGRect.init(origin: CGPoint.init(x: frameOrigin.x + translation.x, y: frameOrigin.y + translation.y), size: frame.size)
          maskedView?.setNeedsDisplay()
          break
          case .ended:
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          case .cancelled:
          frame = CGRect.init(origin: frameOrigin , size: frame.size)
          self.backgroundColor =
          frame.intersects(maskedView!.frame) ?
          UIColor.clear : UIColor.blue
          maskedView?.setNeedsDisplay()
          default:
          break;




          class MyUIView: UIView

          weak var activeMask: ActiveMaskView?

          override func draw(_ rect: CGRect)
          super.draw(rect)
          let ctx = UIGraphicsGetCurrentContext()
          ctx?.setFillColor(UIColor.red.cgColor)
          ctx?.fill(self.layer.bounds)
          ctx?.setBlendMode(.sourceOut)
          guard let activeMask = activeMask , let superview = superview else
          return

          let sc = frame.intersection(activeMask.frame)
          let interSection = superview.convert(sc, to: self)
          ctx?.fill(interSection )








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 0:35









          E.Coms

          1,6302412




          1,6302412











          • hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
            – arvidurs
            Nov 13 at 16:51











          • It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
            – E.Coms
            Nov 13 at 17:24
















          • hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
            – arvidurs
            Nov 13 at 16:51











          • It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
            – E.Coms
            Nov 13 at 17:24















          hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
          – arvidurs
          Nov 13 at 16:51





          hmpf.. I can't believe there is not a simpler solution than this :( this is what I am asking the question for: stackoverflow.com/questions/53221725/animated-color-transition/…
          – arvidurs
          Nov 13 at 16:51













          It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
          – E.Coms
          Nov 13 at 17:24




          It's different. In that case, you show an hidden layer and it's good for mask view. But if you want to hide all layers, mask view can not help here.
          – E.Coms
          Nov 13 at 17:24

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid …


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid …


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244941%2fmask-uiview-with-another-uiview%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          27

          Top Tejano songwriter Luis Silva dead of heart attack at 64

          Category:Rhetoric