I created the instance of the UILabel and added it as the subView of the contentView which is embedded in the table view cell.
Then I created web view (from UIWebView) and added it as the subView on the previously created label. (web view is smaller than label)
And then scrolling over the label,
I found that if touch occurs inside of the web view, scrolling of the table view doesn't work well. It seems that web view captures all the touch events so that its parent (label) doesn't get any touches.
But if touch occurs in the label outside of the web view, scrolling of the table view works well.
I know that if I set setUserInteractionEnabled of web view to 'NO', this problem will be fixed. But web view has some important links that should not be disabled.
Is there any way to make scrolling of the table view work well without disabling user interaction of the web view?
Thanks in advance.
Isn't it a problem caused by your webview trying to scroll ? try
[[[myWebView subviews] lastObject] setScrollingEnabled:NO];
have you tried - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event returning the tableView?
Related
I have UIView that open with a UIButton click. I want to disable user interaction of all other superviews except to this specific view and his subviews, how can I do that? Just to make this view the only view that will response to user touch.
Thanks!
Agree with the comment, you probably want to disable all siblings of a view... (edited so you can set them back to enabled at some point)
- (void)setSiblings:(UIView *)view enabled:(BOOL)enabled {
for (UIView *sibling in view.superview.subviews) {
if (sibling != view) sibling.userInteractionEnabled = enabled;
}
}
I know you already accepted an answer but a better (and easier) approach is to display the new view full screen. Make the new view with a clear background. Then add the real view as a subview to this full screen view. This way you don't have to mess with any existing views to display this new view. You can still see everything behind it but touch events are blocked by the clear, fullscreen view.
Then when you remove this full screen view (fade out animation?) you don't have to mess with all the existing views again.
You shouldn't have to modify existing views just to display another. And what happens if one of those existing views really should have its interaction disabled? You will end up enabling the interaction when you dismiss your "modal" view.
I'm trying to add a UIView on top over the UITableView to mimic the iPhone Facebook style menu. I have it working fine by making the controller a UIViewController then adding a tableview however I am unable to make the menu a static menu unless the controller is a UITableView.
Is it possible to add a view ontop of a tableview and only make the tableview in the background scrollable without the view in the foreground scrolling?
Here is what I have with the subclass being UIViewController
But I am unable to make the tableview cells static via IB since it is not a subclass of UITableView Controller.
EDIT per NSJones Code:
It seems to be going somewhat in the right track. However the view still blocks the table. If I remove the view from the storyboard it will only display the table.
You can make a view hover the same way you make any real thing hover; Hold it up with something invisible.
Basically what you want to do is create a clear UIView (with user interaction disabled) that is the size of your view controller's view, and add it as a subview to your view controller's view property. That way it sits invisibly on top. then you can add a subview to that clear view and that subview won't move.
Edit:
It seems this nice clean approach won't work for you since you need your view controller to be a UITableViewController. The answer for this slightly more complex approach is to use a delegate method for UIScrollView which also works for UITableView. Apple has a fantastic demo of this concept in the WWDC2011 - Session 125 - UITableView Changes, Tips, Tricks video. If you can watch it I highly recommend it. The meat of this issue begins at about 36:10.
But to sum it up you implement the scrollViewDidScroll: delegate method. And handle the movement of the tableview by adjusting the position properties of the view. Here I am keeping an UIView property named viewToKeepStill still using this method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
// CGFloat stillViewDesiredOriginY; declared ivar
CGRect tableBounds = self.tableView.bounds; // gets content offset
CGRect frameForStillView = self.viewToKeepStill.frame;
frameForStillView.origin.y = tableBounds.origin.y + stillViewDesiredOriginY; // offsets the rects y origin by the content offset
self.viewToKeepStill.frame = frameForStillView; // set the frame to the new calculation
}
Instead of adding it as a subview of the table view, add it as a subview of the superview of the table view; that way it won't scroll.
So instead of this:
[tableView addSubview:viewController.view];
Do this:
[tableView.superview addSubview:viewController.view];
Assuming you want something that is visible full-time with the table, start with a view which contains both the menu view and the UITableView. Make the table smaller so it ends where the menu view begins. The table view can work with less vertical space.
If you have your UIViewController's view to be your table view then your table is going to span over the whole screen, so you won't be able to add anything on top of it.
Why not try the following:
1) create a new UIViewController
2) add a view on top where you want your menu
3) in the space left under just drag a table view from the component library
4) don't forget to set the 2 table view delegates to be your view controller class
that's about it?
I'm developing an app that has an UITableViewController with static cells. Those static cells are custom ones and have UITextFields within them. If the user touches one of those textfields, the keyboard pops up. So, after that, what I need to do is to be able to dismiss the keyboard by touching anything on the background. By anything I mean the table view background, its cells and the content of those cells (like the text fields for example).
I used to do this by placing a View in the front of all my other subviews and capture the Touch Inside Up event to dismiss the keyboard. Unfortunately, I can't do this this time because I'm using a UITableViewController and I can't switch it back to an UIViewController because I've already done a lot of work with those static cells.
-(void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event{
[yourTextField resignFirstResponder];
}
Try that.
EDIT
Hi,
I've got your answer :
-(BOOL)isFirstResponder
When you enter something in a text field, it becomes first responder and the keyboard appears. You know that the keyboard is active if [textField isFirstReponder] returns YES.
You may also see that link.may be it will help you.
how to hide the keyboard when empty area is touched on iphone
Well, I found the answer myself. What I need to do was just place programatically an UIView in the foreground and do as I said in the original post. I couldn't do this before because I was trying to achieve that from the Interface Builder.
I have a horizontal UIScrollView that contains UIButtons (though it could be any object). I would like to only download images for these buttons as the user scrolls and they are seen. I would also like an activityindicator running on each button while the images are downloading. Here's what I've tried with results:
Check content offset of uiscrollview and download images for visible buttons. Problem: issues getting activity view shown within subclassed UIButton and not desired usability since images are only downloaded once scrolling stops.
Add subviews (not buttons) to the UIScrollview hoping to use the view's ViewController to initiate a downloaded on viewDidAppear. Problem: viewDidAppear never seems to get called (because I am using addSubView?).
I've seen other apps that do this kind of loading but need some guidance on the typical set-up. Ebay's app is a great example. All items have a default image until the item comes into view, then an activityindicator runs and the items unique image is downloaded.
Thanks for assistance.
Without actually trying it out, here's my idea:
You can use the UIScrollViewDelegate method scrollViewDidScroll: to find out when your scroll view finished scrolling and then use [UIScrollView contentOffset] to determine which part of the scroll view is visible and (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view to determine the button's position within the visible part of the scroll view. Have a method that checks if the button has had its image loaded yet and if not, load it and refresh the view if necessary.
Most such apps are using a UITableView, not a plain scroll view. Joe Hewitt's Three20 framework has a TTImageView class that can do lazy image loading and is pretty well suited to this kind of use.
I am writing an app where I need to show the thumbnail image on each of the table cell, when this thumbnail image is taped it should push new view with larger image. So there should be two touch events on single cell, one for image and other for showing detail view. By default in the didSelectRowAtIndexPath I am invoking detail view which is working fine.
Can someone suggest an approach please.
Thanks,
Bhaskar
The simplest way would be to add the thumbnail in a button as the accessory view of the cell. When the button was hit it would call accessory view method which would load the next view.
from your question, it is understood that you are having a custom cell with an uiimageview in it. In that case, wherever you tap in that cell, may be in the image or the empty portion, the didSelectRow atIndexPath method is invoked. The better way is to use a button to show any of them,, similar to a discloure button in navigators.
I would recommend TechZen's approach: You could add a custom UIButton and place it wherever you like in the cell, and that freedom is nice, but in my experience these tend to really kill scrolling performance. Whatever optimizations are done for accessory views may make them a better experience for your users than buttons.
I agree with Alex. More info: This is what the Detail Disclosure Button accessory view is for on table rows. For an example of this, see the Favorites tab in the Phone application. Tapping on a row calls the person, but tapping on that blue circular button to the right takes you to the detail view for the person's contact info. Another example is the YouTube application.
I think you want something like the YouTube application where tapping on the table cell displays a larger image, and tapping the detail disclosure button takes you to metadata about the image.
See the docs for UITableViewCell for how to add a detail disclosure button. It's very simple.
Since we know that the image is in a cell and I hate subclassing, we can put together a little fun hack. You can just use the cell.imageView property and toss a category on UIImageView:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
if([self.superview isKindOfClass:[UITableViewCell class]]){
if([touches anyObject].tapCount == 1){
//Image was tapped, issue notification, we use the cell as the object
[[NSNotificationCenter defaultCenter] postNotificationName:#"CellImageTapped" object:self.superview]
//just return after the notification
return;
}
}
//if it wasn't a tap, just forward the touch
[super touchesEnded:touches withEvent:event];
}
Then in the table view controller, you can resolve the selected cell by:
NSIndexPath indexOfSelectedCellImage = [self.tableview indexPathForCell:[notificaton object]];
I didn't check, but the superview of the cell.imageView may be the contentView, in that case just substitute in the following:
…if([self.superview.superview isKindOfClass:[UITableViewCell class]])…
…[[NSNotificationCenter defaultCenter] postNotificationName:#"CellImageTapped" object:self.superview.superview]…
Note: Be sure to have your table view controller subscribe to the notification.