I have a UISearchBar working to dynamically show matching results from a list, but having a nightmare trying to stop the searchResultsTableView from obscuring the resultant UIView, which animates in from the right, when the result is tapped.
The magenta view, (including its shadow subview) and the solid black view should be above the list.
I've tried…
self.searchDisplayController.searchResultsTableView.layer.zPosition = 0;
recipeMeasuresView.layer.zPosition = 1;
recipeListView.layer.zPosition = 2;
…but it's messing up the gestures attached still not displaying the views in the correct order. I've also tried…
[self.view sendSubviewToBack:_searchBar];
[ingredientListView bringSubviewToFront:ingredientListView];
…still no joy. Incidently, I'm also adding – amongst other things – [_searchBar resignFirstResponder]; to my
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I'm very much an objective-C newbie so all help greatly appreciated.
In case anybody else stumbles across this with similar problems it seems that the issue is due to the searchDisplayController adding it's own view(s) at the top of the stack, therefore obscuring anything that was added to the storyboard.
There would be no way to push anything up or down to change the order because the searchDisplayResultsTable was being added by a different view controller.
The solution I used was to add the views that were being hidden programatically, meaning I could add them as subviews to different parent views depending on what was happening. Probably not the best solution but it does appear to work.
Related
i am having some very strange issue. Basically i am implementing a drag and drop view with a snap to the horizontal 1D grid. Well, so when i drag a view and its center coordinate X is bigger or smaller then a different view, the non-dragged view should be animated to the left or right of its original position.
This works fine most of the time. But in some special cases its not working. In some situations specific situations the view does not receive any gesture callbacks anymore. I can reproduce this issue and have found out that when i remove the code that applies the animation, everything its working fine.
Basically this is the code that is called when the dragged view is at a position where the view below should be moved to the left or right
/**
* Animate element to its saved position
*/
- (void)switchElement:(unsigned int)draggedIndex with:(unsigned int)otherIndex
{
// first animate
UIView *view = views[draggedIndex];
UIView *otherView = views[otherIndex];
// IF I COMMENT THIS OUT, EVERYTHING WORKS FINE
otherView.frame = [self getImageRectForIndex:draggedIndex];
// now switch internally
if(draggedIndex != otherIndex)
{
// switch views
views[draggedIndex] = otherView;
views[otherIndex] = view;
}
}
Any idea if there is something to have in mind if i animate UIViews and have gesture recognizers attached to them?
If somebody is willing, i can paste the whole class here to test it.
SOLUTION
I am having some "highlight" views in my design. And i have moved the relevant views behind those transparent background views by accident. So now i am not using addSubview: but insertSubview:atIndex: instead.
But marking #Anthonin C. answers as the right one. Because it pointed me in the correct direction (I found it out by overriding the hitTest: method)
Would you please track the otherView.bounds property to verify that your touch isn't out of bounds. I faced this issue recently and Apple documentation provide solution here : Delivering touch events to a view outside the bounds of its parent view
Sorry, I don't have enough reputation to comment your answer.
I've seen the question at some places, but not one helped me. Been searching for a while now, so I'll just ask it here.
I have a problem with UISearchDisplayController. The tableView this is working on doesn't take the whole screen, only the right side:
When I tap the searchBar on top it jumps to this:
And when I actually search, this is what I get:
I've tried several 'solutions' like:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController
*)controller {
controller.searchBar.frame = CGRectMake(300, 20, 744, 44);
}
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
tableView.frame = CGRectMake(0, 0, self.carListDropbox.frame.size.width,
self.carListDropbox.frame.size.height);
}
- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
tableView.frame = self.carListDropbox.frame;
}
They don't seem to help AT ALL. Is there any other way I can lock the searchBar (and UISearchDisplayController) into a view?
Thx!
I attempted to make search controllers work in this way and had many problems with the search results tableview not being in the right position and the search bar not being in the right position either. It seems apple's default design for these animates it to the top and does not really give you much information or control over how this is done.
While I'm not sure if there is a way to lock the searchBar into the view(and get the searchResultsTableView to position properly all the time) because there may be a way to do this that I don't know, but I think it is not worth the trouble.
Instead, I'd recommend making your own search bar and searchresultstableview which you can control, animate and position however you'd like whenever you want to, no headache. Make your searchresultstableview hidden until they enter the text field or start typing in it, then show it as desired. If you want it to look the same you'll have to draw your own search icon and search bar which isn't too difficult with UIBezierPath, or you can add your own images.
I'm trying to take a snapshot of a hidden view but am running into several issues. If I try unhiding it quickly, taking a snapshot, and then rehiding it, I sometimes get a quick flicker on the screen that is pretty jarring.
toCollectionViewCell.hidden = NO;
UIView *toPlaceHolderSnapshot = [toCollectionViewCell resizableSnapshotViewFromRect:toCollectionViewCell.bounds afterScreenUpdates:YES withCapInsets:UIEdgeInsetsZero];
toCollectionViewCell.hidden = YES;
I'm pretty sure the flicker is caused by the afterScreenUpdates:YES, but I can't imagine that is intended behavior.
I've also tried moving the cell/view off screen instead of hiding it, but I can't be certain when that cell might be reloaded and therefore moved back into its place prematurely.
Is there a way to take a snapshot of a hidden view or a more clever way to achieve this? I need this functionality during a custom transition animation where I am pulling a collection view cell out of the collection view and then returning it back into place on dismiss. I am taking snapshots of the before/after state and then transitioning between the two during the animation.
Thanks!
Add an extra container view to your view hierarchy. Hiding the container will have the same visual effect, but you'll be able to snapshot the content of a container with ease.
I've also tried moving the cell/view off screen instead of hiding it, but I can't be certain when that cell might be reloaded and therefore moved back into its place prematurely.
This approach is probably the simplest. As long as all of your work is done on the main thread, the cell won't move during your snapshot.
You could also try archiving and then unarchiving the view (to essentially copy it):
id copyOfView =
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];
UIView *viewCopy = (UIView *)copyOfView;
viewCopy.hidden = NO;
(All views in the hierarchy will need to conform to the NSCoding protocol.)
Finally, you could draw your cell to a UIImage, and then display it in a UIImageView. Sample code here.
This is more or less a continuation of this post: Button in UITableViewCell not responding under ios 7
I am having the same exact issue and have tried every suggestion in the thread. Obviously I don't own that question so I can't edit it to give more info, and thus why I am posting this question now!
Problem:
I have VC nib that I load up that has a tableview in it that I resize based on how many rows are in it. Each row is made from a custom uitableviewcell subclass using a nib file. That class/nib has 4 buttons in it. I can load this code up in iOS 6 or iOS 8 right now and it works perfectly. I don't have a iOS 7 device so I'm bound to the simulator which is at 7.1 (which is the version I'm guess the user that reported this issue was using as well given it was today). Now in the simulator, and the user's phone, I can touch/click everything else on that VC except any of the buttons in the cells. It's as if they had UserInteractionEnabled set to NO, but they don't and neither are any of their parent views (as I'll soon get into).
Tried solutions:
-Completely recreating the nib from scratch both using and not using autolayout
-Calling [self.contentView addSubview:button] in the awakeFromNib of the cell class
-Tried re-adding the buttons to the contentView at runtime with [self.contentView addSubView:button]
-Have ensured four times over that every view in the hierarchy I can find that leads to these buttons have userInteractionEnabled set to YES. (including but not limited to the tableview itself, the cell, the contentView and when I added a "parent view" to the buttons that it was set as well)
-Tried raising all the buttons with a parent view that contains nothing but the buttons
-All buttons are at the top(visually bottom) of the event stack(add and remove are the other two buttons):
-Have set the table cell selection from single to none.
-I am not overriding layoutSubviews in my cell class
-I can not move any views outside of the Content View as Interface Builder takes them completely out of the cell if I do that.
-I have tried disabling the userInteractionEnabled on just the ContentView at runtime with no change
-I tried putting in the cell creation code of the tableview [cell bringSubviewToFront:cell.button]; for the different buttons to the same result.
Hopefully Helpful Facts:
-I tried setting all of the background colors of all of the views in the hierarchy to different colors so I could visually debug it at runtime... it looked exactly as expected. No overlaps or coverings. (This was limited to only views in the cell)
-Here is all of the settings for the TableView:
-I tried to load this in the new XCode 6 to use the visual debugger but the 7.1 simulator included with it actually ran the code perfectly so I could debug it...
-Here is the dequeueing code in the VC:
NiTGroupTimeCell* cell = (NiTGroupTimeCell*)[tableView dequeueReusableCellWithIdentifier:ident forIndexPath:indexPath];
-Here is the code in the viewDidLoad of the VC to set up the cell nib with the table(it's 2 because this is the from scratch one):
[self.timesTable registerNib:[UINib nibWithNibName:#"NiTGroupTimeCell2" bundle:nil] forCellReuseIdentifier:#"GroupTime"];
-All connections were made via IB. These are all using IBAction or IBOutlet.
-I have NSLog statements in all button methods to test if they are actually called, but I have also tested with breakpoints. All are never triggered in testing.
-The only TableView delegate or datasource methods implemented are as follows:
-(int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
-As per suggestion I took Revel to it and found that a mystery UILabel and UIImageView were in the view.... but as you can see their frames are all zeros so they shouldn't be getting in the way of anything so back to where we were I'm afraid:
UILabel frame:
UIImageView frame:
IIRC I counted this off as a Simulator bug before, but since it's happening on the user's device it must be an actual issue and it's holding up my pipeline so help would be GREATLY appreciated! Thanks in advance!
PS I'm happy to post whatever, but because of all the shifting in debugging I didn't know exactly what people would want to see and I didn't want to overload this post because I knew it was going to be long with everything else.
So apparently the issue was these lines of code(in diff format from my git diff output):
--(int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
and
--(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
+-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
so yeah... seems that in iOS7+ if you have the "old" output types for these datasource methods it'll look fine but bork your tableview functionally... good times, but hey it's fixed now^^ hopefully this helps others.
I would suspect that there's an issue with your custom UITableViewCell subclass, NiTGroupTimeCell, or with the IBAction connections from the nib to the tableViewCell subclass.
I also wonder about the extra empty UILabel and UIImageView. They sound like the default properties declared in UITableViewCell.h, UIImageView *imageView and UILabel *textLabel. The fact that they're getting instantiated (and aren't nil) could be a clue as to the weird, unexpected behavior you're seeing.
Do you have IBOutlets to the UIButtons? What about changing properties (in code) for the buttons (such as background color) to make sure you actually are retaining them in the NiTGroupTimeCell.
You're saying that you tried [self.contentView addSubview:button] but your button in your first image is inside a view inside contentView. Try linking an IBOutlet to that view, then try [nameOfView addSubview];
Throwing a wild guess as it looks like you have covered pretty much everything else.
You said:
I load up that has a tableview in it that I resize based on how many rows are in it
And you posted a screen shot saying the clip subviews is off on the UITableView
Are you setting the frame of the tableview incorrectly but its showing the cells anyway due the the subviews not being clipped?
Load up reveal again and check the height of the UITableView
Not sure if it is the case here. But if you name the custom cell outlets imageView, textLabel or any of the "built-in" UITableViewCell's properties you will get weird results and behavior.
You need to check couple of things:
Make sure all the parent views of the button have User Interaction enabled.
Check AutoSizing in the size inspector and make sure the button lies inside the view so it could receive touch events otherwise touch events will get ignore. You can verify it by changing the colour of the view. Changing colour or NSLog the frame of button and parent views will help you to troubleshoot if this is the problem.
Try to make things simpler and don't addSubView programmatically, if designing from IB.
Make sure some component is not overlapping the button with a clearColor background color.
What worked for me is this:
self.contentView.userInteractionEnabled = NO;
I called this after loading my custom cell from nib / storyboard. Without the userinteractionEnabled set to NO, my buttons haven't been responding to touches somehow. My contentView has received all touches and did not forward them to my buttons.
I've seen code where
[cell bringSubviewToFront:button]
has been used as a workaround, for me it did not solve the issue.
I had a simillar issue, while adding Custom Acions based on Guestures.
I was adding Action Button on runtime in Inherited class of UITableViewCell
The bahaviour was if I add buttons outside the visible rect, after animating buttons inside, I was unable to click / tap. But in My Case I was able to Tap / Click if buttons were added in visible rect.
What Worked for me, I added those buttons in View instead of ContentView of UITableViewCell, then animated only Content View. You may try somthing simillar
-- Vishal
You've said that there are no TouchRecognizers(TapRecognizers?), but I think you should double-check that, and look not only for touch recognizers but for any recognizers in controller that uses that cell,even added to self.view/tableView.
I was recently trying to find out why cells don't select(delegate method wasn't called) only to find out that I've added 2 gesture recognizers(in code, those were necessary for other things, but I had to do that in other way) that would prevent cell selection.
Also the sign of it may be that if you hold button long enough(put breakpoint there so you can make it easier), action will fire.
I wanted to show a Settings view, so I figured I could use the pageCurl modal style. I have a UIViewController that I am presenting from:
Settings *settings = [[[Settings alloc] initWithStyle:UITableViewStyleGrouped] autorelease];
settings.view.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
settings.modalTransitionStyle = UIModalTransitionStylePartialCurl;
settings.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentModalViewController:settings animated:YES];
When the page curls, to reveal my UITableViewController below, the cells subviews (labels and accessory views) seem to animate into position, which looks horrible:
The strange thing is, is that the animation never happens to the top cell in a section. This does not happen with other modalTransitionStyle's so I am wondering why this could be happening. It is really becoming frustrating because I cannot figure out how to stop this from happening.
Ideas?
If you set the autoResizingMask property of the tableView to UIViewAutoresizingNone, I think this won't happen. This may be a little bug in the page curl animation.
I've noticed that the direction of this weird animation (which also happens to UIButtons), depends on the Alignment chosen in the Control section of the object's Attributes inspector (in Interface Builder). I've been tinkering with all attributes all evening and have found no solution yet. :(
Edit: so, I had three UIButton in my view (and one UIPickerView) that where doing this weird behavior at the same time. I created a property linking to ONE of the UIButtons. Then, in the viewDidLoad of this view's controller I added the following line:
_firstAffectedButton.titleLabel.autoresizingMask = UIViewAutoresizingNone;
And that fixed it for me, for all the buttons and the picker!! :? Weird, right?
Can anyone explain why this is working? I have the feeling I'm doing something stupid to fix this, but I can't see what it is.
Edit 2: Turns out there was a better and cleaner solution to this problem. See this post.