UIView Mobility Doesn't Get Strokes

I am trying to understand why my subtitle is not getting strokes.

Below is a gif showing the behavior that I am encountering: when I click the blue button on the right, nothing happens (it is assumed that the background from the left corner should change color). When I click the green button on the left, it correctly receives the touch event, the applied TouchDown action fires and the color of the view changes.

enter image description here

This “application” is obviously not a real application and is simply intended to illustrate the behavior that I encounter. Indeed, what I need is to learn how to implement the usual “pop-up menu” template that you see in many applications; usually with an accompanying hamburger button.

In many of these applications, it seems that the main content of the application is being moved to the side to open the menu, "hiding" under the application, one way or another. I am trying to reproduce the same behavior here.

I am embedding ViewController code here. The code you see below is all that I have.

import UIKit class ViewController: UIViewController { var originalX : CGFloat! var originalY : CGFloat! var containerView = UIView() var button : UIButton! var button2 : UIButton! override func viewDidLoad() { super.viewDidLoad() originalX = self.view.frame.origin.x originalY = self.view.frame.origin.y button = UIButton(frame: CGRectMake(200, 25, 100, 100)) button.backgroundColor = UIColor.greenColor() button.addTarget(self, action: "foo", forControlEvents: .TouchDown) view.addSubview(button) containerView.frame = CGRectMake(self.view.frame.width, originalY, 150, self.view.frame.height) containerView.userInteractionEnabled = true containerView.backgroundColor = UIColor.magentaColor() containerView.clipsToBounds = false button2 = UIButton(frame: CGRectMake(25, 25, 100, 100)) button2.backgroundColor = UIColor.cyanColor() button2.addTarget(self, action: "bar", forControlEvents: .TouchDown) view.addSubview(containerView) containerView.addSubview(button2) } @IBAction func left() { UIView.animateWithDuration(0.3) { self.view.frame = CGRectMake(self.originalX - 150, self.originalY, self.view.frame.width, self.view.frame.height) } } @IBAction func right() { UIView.animateWithDuration(0.3) { self.view.frame = CGRectMake(self.originalX, self.originalY, self.view.frame.width, self.view.frame.height) } } func foo() { UIView.animateWithDuration(1.0) { self.view.backgroundColor = UIColor.redColor() } } func bar() { UIView.animateWithDuration(1.0) { self.view.backgroundColor = UIColor.blueColor() } } } 
+4
source share
3 answers

containerView is a subset of view , but the start of containerView belongs to the right edge of its parent view ( view ) due to the line:

 containerView.frame = CGRectMake(self.view.frame.width, originalY, 150, self.view.frame.height) 

Any part of the subset that is outside the bounds of the superview will not receive touch events. Touch events will only be transmitted and recognized by parts of the spy that are within their supervisor. This is why your blue button will not light when you press it.

One way to solve this is, instead of manipulating the view frame, use a secondary subview (call it overlayView ) to overlay and close the containerView , as well as manage its frame. Make sure that at least some parts of both views are within the main view so that they can receive touch events.

+10
source

You need to keep the main view large enough to receive events. Use self.view.frame.width + 150 as the third argument to CGRectMake in left() .

However, this is a strange and fragile decision for what you are trying to do. You should not move the frame of the main view. This should remain covering all UIWindow , nothing more, nothing more. You only want to liven up the subviews and think about whether you really use the PageViewController idiom , CollectionView idiom, UIScrollView idiom or SpriteKit . And think about why you want to move the center control buttons and center mark, creating an unusually “jumping” interface.

One fragility performs layout calculations in viewDidLoad() , which is too early in the ViewController life cycle. See: wrong frame size in viewDidLoad

The right way is a good job: restrict the user-defined subclass of UIView to populate the main view, and then if you need to do the layout calculations for the layoutSubviews() code, do it in the overridden layoutSubviews() method of that user-defined subclass - the correct geometry is available at this point. (However, adding subtasks to a custom subclass of UIView in code should not be done in layoutSubviews () `, but instead when building or waking up.)

Things get a lot easier if your main view does not need to be moved. If you are free to read in Objective-C, try: http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/

Then you get a real separation of concerns where your slide settings are truly standalone. Quote:

The interaction was supposed to create. Its nothing special - just a view appearing from the right edge of the screen. What is special is that they actually represent the view controller, even though the data view controller remains visible.

0
source

For your code, you add containerView to self.view, however its frame is not in self.view.bounds, so containerView cannot get any touch, so you should do

  • just make sure self.view is big enough to contain containerView , at least contains button2

or

  • just an animation of the containerView frame to make it self.view
0
source

All Articles