UIButton losing target after rotation - ios

I have(/had) a UITextField subclass which has a custom delete button as a rightView property.
This is working fine up until I rotate the device and then the button does not react anymore.
I changed my approach and 'cheated' a bit. Now I'm adding the UIButton on top of the UITextField in code. Which also works fine up until I rotate the device. I checked with backgroundColors if there are no other elements on top of the button.
I also tried removing the button and adding it again when the device rotates. It's visible but the action does not trigger. If I start my app in Portrait or in Landscape it works up until I rotate the device.
How I add the button:
if (!btn_delete)
{
btn_delete = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width - 70, (tf_search.frame.size.height / 2) - 8, 17, 16)];
[btn_delete setImage:[UIImage imageNamed:#"icon_cross_textfield"] forState:UIControlStateNormal];
[btn_delete addTarget:self action:#selector(clearTextField:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn_delete];
[self.view bringSubviewToFront:btn_delete];
}
else
{
[btn_delete removeFromSuperview];
btn_delete = nil;
}
Method -(void)clearTextField:(UIButton*)sender does not get called after rotation.
Any advice is appreciated.

The UIButton was added to a UIViewController's UIView which was part of a UIView of another UIViewController. They all had clearColour as backgroundColor so the UIButton was still visible but not in the bounds of the superView.

Related

Custom UIButton No Longer Works After Changing UIView to UIViewController

This code worked in a UIView container, but after changing that container to a UIViewController, the code no longer works:
-(void)viewDidLoad
{
[super viewDidLoad];
[self.view setUserInteractionEnabled:YES];
// set button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(60, 30, 220, 220);
[button setImage:self.obj.img forState:UIControlStateNormal];
[button addTarget:self action:#selector(selected:) forControlEvents:UIControlEventTouchUpInside];
[button setUserInteractionEnabled:YES];
[self.view addSubview:button];
}
-(void) selected:(UIButton *) button // also tried (id) sender
{
NSLog(#“Button Selected“);
}
These containers are created programmatically (dynamically), from web services, so I cannot use Storyboard. The reason for changing to a UIViewController is that I need a segue to another screen. Also, these containers are placed in a UIScrollView.
Everything else is working properly, except the selector.
Setting the userInteraction wasn't necessary earlier, but I've gone ahead and tried that in different configurations. I've added this to the scrollview, the viewController, and the button, just for good measure.
I even tried some online tutorials for programmatically creating UIButtons in UIViewControllers and was able to do that just fine. Not sure what the issue is here. Thanks.

Having a UIButton be tapped in a UICollectionViewCell

I have a UICollectionView with its cells all laid out.
I have this declared as a subview:
#property (nonatomic, strong) UIButton *aButton;
I then have that declared in each cell like so:
if (_aButton == nil)
{
_aButton = [UIButton buttonWithType:UIButtonTypeSystem];
}
// Add in all _aButton info here
[self.contentView addSubview:_aButton];
// Call to button pressed for button
[_aButton addTarget:self action:#selector(aButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
The button click method is like so:
- (IBAction) aButtonPressed:(UIButton *) sender
{
// Code never gets heree
}
The if(_aButton== `nil) is needed since cells get reused.
How do I make this work now? Thanks.
Add button action code before button added to view.... May be it will work .
// Call to button pressed for button
[_aButton addTarget:self action:#selector(aButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
// Add in all _aButton info here
[self.contentView addSubview:_aButton];
I think, the way you are initializing the button is going to give you frame as 0,0,0,0 . So first give it a proper frame and title to be visible on the screen.
Then try tapping on that title and see if it works or not.
It's unclear what you trying to achieve here, but the button is not working because you not setting it's position and size on the cell. It could be done by setting frame or layout constraints.
Try to set button frame:
_aButton.frame = CGRectMake(0.0f, 0.0f, 50.0f, 50.0f);
You can also set background color for the button, just to make it visible on the cell:
_aButton.backgroundColor = [UIColor redColor];
Everything else is correct, button should work.

UIButton center position doesn't update with rotation

I have a program that dynamically generates UIButtons in the center of
the screen with push of another button.
The buttons are not updating the x-coordinates when I rotate the device.
Here is my code for creating buttons:
- (IBAction)createButton:(UIButton *)sender {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundColor:[UIColor redColor]];
[button addTarget:self action:#selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(self.xCoord,self.yOffset,100.0,120.0);
[self.view addSubview:button];
_yOffset = _yOffset+130;
}
The XCoord and self.yOffset were set in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
self.yOffset = 109;
self.xCoord = self.view.bounds.size.width/2-50;
}
The coordinates of the button in your code are fixed once they've been added to the view. If you want to update the frame of the buttons when the screen rotates, you'll need to trigger the repositioning of the buttons when the screen rotates.
AutoLayout in a storyboard makes this easier (if you just want a button to appear then you can add it in a storyboard and change its hidden property from NO to YES when the other button is pressed -- this won't be helpful if you want to add an arbitrary number of buttons, although you could have a hidden placeholder view that you use as a positioning reference)
If you want to keep the buttons x-position, you need to add Auto Layout constraints. There are a couple ways to do this programmatically. You can use the NSLayoutConstraint object directly or use Auto Layout's Visual Format Language. For more info, see Apple's documentation.

UIView/UIButton coordinates flipped

I have a coreplot project. The class of the view in viewcontroller has been changed to CPTGraphHostingView.
After creating the graph (this works fine),
I am adding a button as a subview , this launches a popover
the button shown is inverted. I have the same control in different view controllers and it works fine. The Popover also appears fine.
Here is the code that creates and adds the UIButton
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(monthSelection)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Change Month" forState:UIControlStateNormal];
button.frame = CGRectMake(330, 650, 111, 40);
[self.view addSubview:button];
[here is a screenshot of whats happening. UIButton is suppose to show somewhere below the popover. What am i missing.
Do not add subviews to the graph hosting view. Instead, make other views siblings of the hosting view, i.e., add them as subviews of the same superview.

Programmatically adding a view with a button

I want to add a view and a button programmatically like follows.
The problem is that the button does not react on clicking. I mean neither does it get highlighted or calls the selector.
The reason is that I want to implement a list row for a recording (a sound file). The list row should be selectable for drill-down and have a play button. So I got a RecordingView subclassing UIView that itself adds the button using a target from the constructor. See code below.
If anyone has a better approach to do this that could also be a solution.
#implementation MyViewController
- (IBAction) myAction {
RecordingView *recordingView = [[RecordingView alloc] initWithFrame:CGRectMake(30, 400, 130, 50)withTarget:self];
[recordingView setUserInteractionEnabled:YES];
[[self view] addSubview:recordingView];
}
#implementation RecordingView
- (id)initWithFrame:(CGRect)frame withTarget:(id) target
{
self = [super initWithFrame:frame];
UIButton *playButton = [[UIButton alloc] initWithFrame:CGRectMake(185, 5, 80, 40)];
[playButton setTitle:#"Play" forState:UIControlStateNormal];
[playButton setTitleColor:[UIColor darkTextColor]forState:UIControlStateNormal];
// creating images here ...
[playButton setBackgroundImage:imGray forState: UIControlStateNormal];
[playButton setBackgroundImage:imRed forState: UIControlStateHighlighted];
[playButton setEnabled:YES];
[playButton setUserInteractionEnabled:YES];
[playButton addTarget: target
action: #selector(buttonClicked:)
forControlEvents: UIControlEventTouchDown];
[self addSubview:playButton];
return self;
}
When I add the button the same way, directly in the view controller .m-file, the button does react on clicking. So there is something about the RecordingView. What do I need to do different here?
Also, are there any better ways to provide the target and selector for the touch event?
You may simply need to set userInteractionEnabled to YES on your RecordingView.
Another problem is that you are creating the RecordingView with a frame width of 130, but you are setting the X-axis origin of playButton to 185. This means playButton is entirely outside of the bounds of its superview. The default value for clipsToBounds is NO, so the button is drawn anyway. But touch events will never reach the button, because they are rejected when the system hit-tests the RecordingView.
This is from the hitTest:withEvent: documentation in UIView Class Reference:
Points that lie outside the receiver’s bounds are never reported as hits, even if they actually lie within one of the receiver’s subviews. This can occur if the current view’s clipsToBounds property is set to NO and the affected subview extends beyond the view’s bounds.
You need to either make RecordingView's frame wider, or move playButton to be inside the bounds of its superview.

Resources