How to allow swiping over UIButtons to scroll? - ios

I have a carousel menu of UIButtons in my app. Everything works great except that the buttons are kinda big and it won't scroll when a finger is dragged across the button. The dragging has to be done outside of the button that's currently front and center in the carousel. Is there some setting I can change so that I can swipe across the buttons to scroll and have them also be interactable?
Here's the code that creates the buttons:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 500.0f, 320.0f);
button.layer.cornerRadius = 8.0f;
button.layer.masksToBounds = NO;
button.layer.borderWidth = 0.0f;
button.layer.shadowColor = [UIColor blackColor].CGColor;
button.layer.shadowOpacity = 0.8;
button.layer.shadowRadius = 12;
button.layer.shadowOffset = CGSizeMake(12.0f, 12.0f);
[button setImage:(UIImage*)[buttons objectAtIndex:index] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];

Make sure UIScrollView property canCancelContentTouches is set to YES.
scrollView.canCancelContentTouches = YES;
Moreover, a UIScrollView implements a method touchesShouldCancelInContentView.
The default returned value is YES if view is not a UIControl object;
otherwise, it returns NO.
This means that UIScrollView does not attempt to cancel touches in UIButtons which prevents scrolling. Additionally, you can subclass UIScrollView and override touchesShouldCancelInContentView to return YES when content view object is a UIButton.

Related

bringSubViewToFront not working

I have an image created in storyboard. And I added an button programmatically and added to view.
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
button.frame = CGRectMake(30,30,30,30);
button.layer.borderColor = [[UIColor blackColor] CGColor];
button.layer.borderWidth = 0.5f;
[imageView addSubview:button];
These two are overlapping and button behind is invisible, but its action can be performed. I try to bring this button over image using,
[imageView bringSubViewToFront:button];
But its not working.
there is no chance that button will be behind imageView if u write so .there must be a time u adjust two views' relation after u add button the the imageView.
After create button programatically and put that button in subview of imageview, Make sure make your imageview property Userinteraction Enabled TRUE.
Use this statement, hopefully it works:
[imageView setUserInteractionEnabled:TRUE];

Is it possible to dim a UIView but allow touch of elements behind it?

How would you have a grey overlay on top, but allow to touch buttons beneath it?
You can set userInteraction of overlay to false.
As mentioned, you can set userInteractionEnabled to NO.
But pay attention: when you create a full screen transparent view, and set its userInteractionEnabled to NO, all the subviews of that view will not be responsive to user actions. If you add a button on your view, it will not respond to user taps! and another problem: if you set the alpha value of that view to be transparent, e.g. 0.4, then all its subviews will be transparent too!
The solution is simple: don't put any subview on your transparent view, but instead, add your other elements as siblings of your view. Here is Objective-C code to show what I mean: (notice the comments which say it all):
//Create a full screen transparent view:
UIView *vw = [[UIView alloc] initWithFrame:self.view.bounds];
vw.backgroundColor = [UIColor greenColor];
vw.alpha = 0.4;
vw.userInteractionEnabled = NO;
//Create a button to appear on top of the transparent view:
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 80, 44)];
btn.backgroundColor = [UIColor redColor];
[btn setTitle:#"Test" forState:UIControlStateNormal];
[btn setTitle:#"Pressed" forState:UIControlStateHighlighted];
//(*) Bad idea: [vw addSubview:btn];
//(**) Correct way to have the button respond to user interaction:
// Add it as a sibling of the full screen view
[self.view addSubview:vw];
[self.view addSubview:btn];

View with subviews in a uinavigationbar and uitoolbar

I really need your help with this one (first post on SO -- be gentle):
I have two dynamic UIButtons which I would like to have centered in a UIView, which in turn should be centered in a UINavigationbar and UIToolbar. I can't - despite a lot of Googling - seem to figure out a proper way to do this.
This is what I've done so far:
In viewDidLoad, I add the two buttons as subviews and set the view as the UINavigationbar's titleView
self.myClass.viewForTitleAndButton = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 32)];
[self.myClass.viewForTitleAndButton setBackgroundColor:[UIColor blackColor]];
[self.myClass.viewForTitleAndButton addSubview:self.myClass.myButton];
[self.myClass.viewForTitleAndButton addSubview:self.myClass.myOtherButton];
self.navigationItem.titleView = self.myClass.viewForTitleAndButton;
In a method being triggered when I press certain buttons, I set the title (and bounds) of one of the buttons depending on what's clicked:
CGSize titleSize = [title sizeWithAttributes:#{NSFontAttributeName : [UIFont italicSystemFontOfSize:17.0]}];
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGFloat newX = (screenSize.width - titleSize.width) / 2;
CGRect buttonFrame = self.myClass.myButton.frame;
//Removing the line below doesn't do any difference at the moment
self.myClass.myButton.bounds = CGRectMake(newX, buttonFrame.origin.y, titleSize.width+8, buttonFrame.size.height);
[self.myClass.myButton setTitle:title forState:UIControlStateNormal];
NSLog(#"Title: %#", title);
//title is a NSString that changes depending on what is clicked. I am 100% sure it changes as I can see it in the log every time the method is triggered.
The problem is that the title of myButton is not changed. It worked before with the very same button when it was placed in a different spot and not as a subview.
Q1: What am I missing to make the title of the button change?
Q2: Is adding the buttons as subViews to a view that is then placed in the navigationbar and toolbar respectively a sound way to accomplish what I want?
This is really bugging me, any pointers in the right direction is much appreciated.
I don't think you can add a button which is already an outlet of a view controller. Thinking in another way, a button(view) can only has one superview.
Create button dynamically for the title view.
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *iv = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 160, 44)];
iv.backgroundColor = [UIColor greenColor];
titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
titleButton.frame = CGRectMake(0, 0, 120, 44);
[titleButton setTitle:#"test" forState:UIControlStateNormal];
[titleButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[iv addSubview:titleButton];
self.navigationItem.titleView = iv;
}
//some event to change the button title
- (void)click:(UIButton *)button
{
[titleButton setTitle:#"I changed" forState:UIControlStateNormal];
}

Get rid of padding for UITableViewCell custom accessoryView

I have a table view cell with a custom accessoryView, but it seems that the way it's laid out by default creates a 15-point margin on the right side. I want to get rid of it.
I can achieve the desired effect by overriding layoutSubviews, but that breaks edit mode animation (the accessory no longer slides in/out).
Any better way to do this?
Add subview instead of accessoryView
UIButton *deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
deleteBtn.frame = CGRectMake(cell.contentView.frame.size.width-55, 2, 50, 50);
[deleteBtn setBackgroundImage:[UIImage imageNamed:#"trash.png"]
forState:UIControlStateNormal];
deleteBtn.backgroundColor = [UIColor clearColor];
//deleteBtn.alpha = 0.5;
deleteBtn.tag = indexPath.row;
[deleteBtn addTarget:self action:#selector(numberDeleteConfirm:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:deleteBtn];

Adding a close button to the modal view that is partially off the view

I am trying to add a "X" button to the top of the modal view so if the user presses that it closes the modal view. I looked at the solution proposed here how to add close button to modal view corner which is presented in UIModalPresentationPageSheet?
But I have two follow up questions here as i am fairly new to ios programming
The solution proposed in the above page does not seem to work for me. I tried it with a normal button first in the viewDidLoad of the modal VC and I am seeing it appear only within the bounds of modal view and not outside as I want.
UIView *buttonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
buttonView.backgroundColor = [UIColor brownColor];
CGRect buttonFrame = CGRectMake( 0, 0, 100, 50 );
UIButton *button = [[UIButton alloc] initWithFrame: buttonFrame];
[button setTitle: #"Close" forState: UIControlStateNormal];
[button setTitleColor: [UIColor redColor] forState: UIControlStateNormal];
[button addTarget:self
action:#selector(closeButtonPressed)
forControlEvents:UIControlEventTouchUpInside];
[buttonView addSubview: button];
CGRect parentView = self.view.superview.frame;
CGRect currentView = self.view.frame;
CGRect buttonViewFrame = buttonView.frame;
buttonViewFrame.origin = CGPointMake(parentView.origin.x - buttonViewFrame.size.width/2.0f, parentView.origin.y - buttonViewFrame.size.height/2.0f);
[buttonView setFrame:buttonViewFrame];
[self.view addSubview:buttonView];
what I am seeing is
How do I draw the "X" button do I use CGRect to draw it our or instead of adding a button in the above example should I just add a image with the "X" in it as the subview?
thanks in advance for the help
do like this, hope helps u :)
//adding button to your view
UIView *aView = [[UIView alloc]initWithFrame:CGRectMake(100, 200, 300, 350)];
aView.backgroundColor = [UIColor blueColor];
aView.tag = 100;
[self.view addSubview:aView];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setTitle:#"CLOSE" forState:UIControlStateNormal];
[aButton addTarget:self action:#selector(tapped:) forControlEvents:UIControlEventTouchUpInside];
aButton.frame = CGRectMake(aView.bounds.origin.x, aView.bounds.origin.y, 80, 30);// adjust with respect to bounds
aButton.backgroundColor = [UIColor redColor];
[aView addSubview:aButton];
[aView release]; //i am doing without ARC
The other option is to create a larger view and put your UITableView within this, along with your close button. The close button can then be at position (0,0) and the UITableView can start at (25,25).
This prevents complications - I have seen clipped views fail to recognise the touch outside of the main view, so your 50x50 button only has a touch area of 25x25.

Resources