Buttons not responding to touch in scrollview - swift

I have a UIView in a UIScrollView and under the UIView there are some labels, and two buttons.
Everything works fine, except the buttons. They do not respond to touch.
Everything is done in Storyboard and the labels and buttons are all using autoresize
I have tried to add:
scrollView.canCancelContentTouches = true
scrollView.delaysContentTouches = true
To no effect.
The view hierarchy is as follows:
-View
--Scroll View
---View
----Label
----Label
----More Labels
----Button
----Button

Write your own class subclass UIScroll view and add below code
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
return NO;
}
or modify your code
scrollView.canCancelContentTouches = false
scrollView.delaysContentTouches = false

The view hierarchy is as follows:
-View
1.--Scroll
2---View . <--- Check this UIVIEW User interaction is Enable or disable
3----Label
4----Label
5---More Labels
6----Button
7----Button

Related

disable tableHeaderView (Not to be confused with section header) scrolling

Is it possible to disable the scrolling of tableHeaderView (Not to be confused with section header).Right now whenever I scroll the table, view in the tableHeaderView also gets scrolled.
What i am doing:
I have a class subclassed from UITableViewController.
In storyboard, I am using the static table view.
Table style is Grouped and I have added 8 sections having a row each.
On the top of 1st section, added a view which is the tableHeaderView.
I want to disable the scrolling of view with title "Profile" when I scroll the table.
PS:
I know this is achievable if I subclassed my class from UIViewController instead of UITableViewController.
But I don't want to UIViewController because I am using storyboard for designing static cell and If I use UIViewController instead of UITableViewController then compiler throws a warning "Static table views are only valid when embedded in UITableViewController instances"
Please let me know which is the best approach to achieve this.Is it possible to disable the scrolling of tableHeader using my current approach or do I need to use UIViewController instead.
Just use an embed segue with a parent UIViewController consisting of a header view and a container view. Embed your UITableViewController in the container view. More specific steps in this answer.
If you want everything in UITableViewController, you can insert your own subview doing something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.header = [[UIView alloc] init];
self.header.frame = CGRectMake(0, 0, self.tableView.bounds.size.width, 44);
self.header.backgroundColor = [UIColor greenColor];
[self.tableView addSubview:self.header];
self.tableView.contentInset = UIEdgeInsetsMake(44, 0, 0, 0);
}
and then manipulate the position of the view in scrollViewDidScroll and friends:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
self.header.transform = CGAffineTransformMakeTranslation(0, self.tableView.contentOffset.y);
}
I say "and friends" because you'd need to take care of the corner cases like scrollViewDidScrollToTop:. scrollViewDidScroll gets called in every display cycle during scrolling, so doing it this way looks flawless.
Timothy Moose was spot on. Here are the necessary changes for iOS8.
MonoTouch (C#)
// create the fixed header view
headerView = new UIView() {
Frame = new RectangleF(0,0,this.View.Frame.Width,44),
AutoresizingMask = UIViewAutoresizing.FlexibleWidth,
BackgroundColor = UIColor.DarkGray
};
// make it the top most layer
headerView.Layer.ZPosition = 1.0f;
// add directly to tableview, do not use TableViewHeader
TableView.AddSubview(headerView);
// TableView will start at the bottom of the nav bar
this.EdgesForExtendedLayout = UIRectEdge.None;
// move the content down the size of the header view
TableView.ContentInset = new UIEdgeInsets(headerView.Bounds.Height,0,0,0);
.....
[Export("scrollViewDidScroll:")]
public virtual void Scrolled(UIScrollView scrollView)
{
// Keeps header fixed, this is called in the displayLink layer so it wont skip.
if(headerView!=null) headerView.Transform = CGAffineTransform.MakeTranslation(0, TableView.ContentOffset.Y);
}
[Export ("scrollViewDidScrollToTop:")]
public virtual void ScrolledToTop (UIScrollView scrollView)
{
// Keeps header fixed, this is called in the displayLink layer so it wont skip.
if(headerView!=null) headerView.Transform = CGAffineTransform.MakeTranslation(0, TableView.ContentOffset.Y);
}

Disable the parent view when subview opened

I have two views. viewController and myCustomAlert. i have added myCustomAlert as a subview in viewController.
this is the function which is called when myCustomAlert is added as a subview.
-(void)ratingAction:(id)sender
{
if ([sender isKindOfClass:[UIButton class]])
{
[[NSBundle mainBundle] loadNibNamed:#"myCustomAlert" owner:self options:nil
];
Custom_view.frame = CGRectMake(10, 100, 287, 165);
[self.view addSubview:Custom_view];
self.view.userInteractionEnabled = false;
Custom_view.userInteractionEnabled = true;
}
}
i want parent view to be disabled so i disable the userinteraction but it disable the subview too. how to do that?? i want my subview to work like an alert.
One approach you can try is set subviews frame in a way that it completely hides its super view controller i.e. 0,0,320,460 and make sure that the content on subviews are properly placed at position where you want, and then make the background color of subview transparent.
myCustomAlert.backgroundColor = [UIColor clearColor];
when you add a subview to a specific view, the subview and parent become one view collectively, i.e. the parent view. so disabling interaction will disable both.
for you is to present modelview controller with animated property as false and disable parent view interaction. tell me if you achieve your goal

Convert UIViewController to UIScrollViewController

I am new to iPad developer,
I made one Registration form in my application, when i see my application in Portrait mode,
i am able to see whole form with no scrolling, but when i see same form in Landscape mode, i am not able to see part which is at bottom of page, for that a scrolling should be there to see bottom part.
:
In my .h file when i replace
#interface ReminderPage : UIViewController{
...
...
}
:UIViewController with :UIScrollView
and then when i add label in my .m file like this,
UILabel *Lastpaidlbl = [[[UILabel alloc] initWithFrame:CGRectMake(70 ,400, 130, 50)]autorelease];
Lastpaidlbl.backgroundColor = [UIColor greenColor];
Lastpaidlbl.font=[UIFont systemFontOfSize:20];
Lastpaidlbl.text = #"Lastpaid on :";
[self.view addSubview:Lastpaidlbl];
I am getting error on last line Property view not found on object of type classname.
i am unable to add label in my view.
Any help will be appreciated.
The question appears to be really asking how can all the components on the screen be placed inside a UIScrollView, rather than a UIView. Using Xcode 4.6.3, I found I could achieve this by simply:
In Interface Builder, select all the sub-views inside the main UIView.
Choose Xcode menu item "Editor | Embed In | Scroll View".
The end result was a new scroll view embedded in the existing main UIView, will all the former sub-views of the UIView now as sub-views of the UIScrollView, with the same positioning.
If you want to replace your UIViewController with a UIScrollView, you will have to go a bit of refactoring to your code. The error you get is just an example of that:
the syntax:
[self.view addSubview:Lastpaidlbl];
is correct if self is a UIViewController; since you changed it to be UIScrollView, you should now do:
[self addSubview:Lastpaidlbl];
You will have quite a few changes like this one to make to your code and will face some issues.
Another approach would be this:
instantiate a UIScrollView (not derive from it);
add your UIView (such as you have defined it) to the scroll view;
define the contentSize of the scroll view so to include the whole UIView you have.
The scroll view acts as a container for your existing view (you add your controls to the scroll view, then add the scroll view to self.view); this way, you could integrate it within your existing controller:
1. UIScrollView* scrollView = <alloc/init>
2. [self.view addSubview:scrollView]; (in your controller)
3. [scrollView addSubview:<label>]; (for all of your labels and fields).
4. scrollView.contentSize = xxx;
I think the latter approach will be much easier.
Please put all of your UIComponents to the UIScrollview and then it will start scrolling.
please look in to content size. please change it according to the orientation of device.
You're subclassing UIScrollView, so there is no self.view because already self is the view (of the scrollview). You dont need to subclass the scrollview, you can just embed your components in a ivar scrollview and set its contentSize (in your case, you have to enable the scrolling just when the device is in landscape mode). In interface builder you can embed the selected elements in one click, Editor-> Embed in-> scrollview.
First create scrollview
UIScrollView * scr=[[UIScrollView alloc] initWithFrame:CGRectMake(10, 70, 756, 1000)];
scr.backgroundColor=[UIColor clearColor];
[ self.view addSubview:scr];
second
change [self.view addSubview:Lastpaidlbl];
to
[scr addSubview:Lastpaidlbl];
third
set height depends on content
UIView *view = nil;
NSArray *subviews = [scr subviews];
CGFloat curXLoc = 0;
for (view in subviews)
{
CGRect frame = view.frame;
curXLoc += (frame.size.height);
}
// set the content size so it can be scrollable
[scr setContentSize:CGSizeMake(756, curXLoc)];
Finally
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight) {
self.scr.frame = CGRectMake(0, 0, 703,768);
} else {
self.scr.frame = CGRectMake(0, 0, 768, 1024);
}
return YES;
}

How To disable the userinteraction of a view except one object?

In My view there is reset button .i need userinteraction disabled except for that button .how can i do that can any one share the code.thanks in advance?
btn1 is your button, self.view - your view
for (UIView *view in self.view.subviews)
view.userInteractionEnabled=NO;
btn1.userInteractionEnabled=YES;
For all the elements there is a property userinteractionenabled. Set it to false
yourelement.userInteractionEnabled = NO;
Also place your UIButton on top of your view hierachy.
Other option is to place a tranparent UIButton on your entire view and your UIButton on top of this view. This way only your UIButton is touch enalbed. Other touches would be taken in by the transparent button which does nothing.
Sligthly better approach, define a "magic value" that will help you :
#define kDontDisableUserInteraction 3928473
then set this value as the tag of your button you don't want disabled:
[resetButton setTag:kDontDisableUserInteraction];
you can now create a function in your superview's class :
- (void)setInterfaceEnabled:(BOOL)newEnabled {
for (UIView *subview in self.subviews) {
if (subView.tag != kDontDisableUserInteraction)
continue;
subView.userInteractionEnabled = newEnabled;
}
}
That allows you to create other non-disableable buttons simply by giving them the right tag (which can be whatever int value you want, not only 3928473, depends on your #define).

UIButton Doesn't allow UIScrollView to scroll

I have many UIButtons within a UIScrollView. Those UIButtons have actions attached to them in Touch Down Repeat. My problem is my scroll view doesn't scroll when I touch a button then scroll, but it works fine if I touch outside of the button.
How can I allow my scroll view to scroll even though a button is pressed?
As long as you have the Cancellable Content Touches in Interface Builder set it should work. You can also set it in code:
scrollView.canCancelContentTouches = YES;
So view.canCancelContentTouches = YES works OK if you don't also have delaysContentTouches set to YES. If you do though, the buttons won't work at all. What you need to do is subclass the UIScrollView (or UICollectionView/UITableView) and implement the following:
Objective-C
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
if ([view isKindOfClass:UIButton.class]) {
return YES;
}
return [super touchesShouldCancelInContentView:view];
}
Swift 2
override func touchesShouldCancelInContentView(view: UIView) -> Bool {
if view is UIButton {
return true
}
return super.touchesShouldCancelInContentView(view)
}
Use a UITapGestureRecognizer with delaysTouchesBegan as a property set to true.