I'm having a weird issue when I resize a MKMapView in iOS 6.
Basically this is my escenario:
I have a UITableView showing a MKMapView in every cell.
In iOS 5 it looks like this:
http://cl.ly/image/0e0R1623413s
And in iOS 6 it looks like this:
http://cl.ly/image/2C041E3B3k1X
When the cell is selected I call an UITableViewView beginUpdates, endUpdates block,
to change the size of the cell and with the autoresizing mask of the MKMapView it gets resized.
[self.tableView beginUpdates];
[self.tableView endUpdates];
After the beginUpdates, endUpdates block this is what I get in iOS 5 (it works like charm):
http://cl.ly/image/3Q0O0q1S0E3N
But in iOS 6 the MKMapView gets blank showing only the 'Legal' link
http://cl.ly/image/443x2r2D3l44
I've couldn't found any useful information about this issue and I'm getting crazy about this.
The only reference I got about a similar problem is this thread in the Apple Developer forums:
https://devforums.apple.com/message/733353#733353
However, the problem is different and the only advice is to do the things
on main thread and with the MKMapView visible. In my case
the animation is made on the main thread and the view is also visible,
so that's not the problem apparently.
Does anyone have some advice, thought or idea to solve this issue?
Thanks in advance.
I have a similar problem after I upgrade my app to iOS6. I suspect that it is related to the selection style. My workaround is to set selectionStyle to UITableViewCellSelectionStyleNone. My map views do not disappear anymore. You can try to see if that helps.
Related
I have a view controller that is setup with a UITableView in UIStoryboard. The UITableView is constrained to the SafeArea of the controller on all four sides.
It may seem that this question has been asked before, but each time I have found the question, it is because there are changes taking place in viewDidLayoutSubviews that cause the loop to occur. I have a blank implementation of viewDidLayoutSubviews and basic UITableViewCells (no nib). Yet in iOS 11, Xcode 9.2, flicking the tableview up causes viewDidLayoutSubviews to be called on an endless loop. This is my implementation:
- (void)viewDidLayoutSubviews {
NSLog(#"viewDidLayoutSubviews");
[super viewDidLayoutSubviews];
}
I cannot figure out for the life of me how this is happening.
Edit: The controller has a NavigationController and is the Master controller of a UISplitViewController, which is embedded in a BannerViewController (from iAdSuite example).
Edit: This happens on iOS 11 (up through 11.2) on ALL devices on the simulator. Does NOT happen iOS 10.3. viewDidLayoutSubviews isn't even called in iOS 10.3. I get the same results when I simply use the Nav Controller with the UIViewController/TableView in place of the UISplitViewController/BannerViewController. So seems that the issue is not introduced there, but from something that is happening in iOS 11.
EDIT: So this is odd - seems it is happening only when large titles are selected for the navigation controller!
if (#available(iOS 11.0, *)) {
self.navigationController.navigationBar.prefersLargeTitles = YES;
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
}
EDIT: This problem can be easily reproduced. I downloaded Apple's iAd Suite sample code, and used the SplitNavigationController project. I updated the project for iOS 11, including updating the storyboard to use Safe Area Layout Guides. I changed the MasterViewController from a UITableViewController to a UIViewController with a UITableView, which I constrained to the Safe Area layout guides in the storyboard. I added in prefersLargeTitles and largeTitleDisplayMode to the MasterViewController. I added in the viewDidLayoutSubviews method, with a NSLog statement, so this behavior can be easily observed. I think this is a real problem with iOS 11, and I will try to get to the bottom of it, and I would also appreciate if anyone else can offer any thoughts or suggestions.
EDIT: matt was able to reproduce this issue and post it in a GitHub project, to be found at the following link (thanks matt!): InfiniteLayoutSubviewsBug
EDIT This was definitely a bug in iOS 11 thru at least iOS 11.2, but in iOS 12 the bug no longer exists.
It looks like you've found a bug. I was able to reproduce the problem in a minimal example project, which I've posted at GitHub here:
https://github.com/mattneub/InfiniteLayoutSubviewsBug
Download the project and run it. You'll see a simple table with three rows. Scroll the table view up and let go. Watch the console. We are getting repeated calls to viewDidLayoutSubviews, once every 1/60 of a second, forever.
Note that this is not caused by a recursive layout loop in our code. My example doesn't even call super. All it does is log. This is the runtime itself calling viewDidLayoutSubviews repeatedly forever. No code of ours (except print) runs while this is happening.
Other observations:
As you rightly observed, if you change the example so that the navigation bar doesn't use large titles, the problem goes away.
If you change the example so that the table view is not positioned using autolayout, the problem goes away.
If you change the example (rather more elaborately) so that the view controller is a UITableViewController subclass, the problem goes away; we get some repeated calls to viewDidLayoutSubviews but not forever, just while scrolling.
I have spent countless hours trying to get SWTableViewCell working, and I've run out of ideas. I'm trying to integrate it into a UITableViewController that contains a custom UITableViewCell (subclassed). For some reason, I can't get any of the animation working. I thought at first that MMDrawerController might have been causing the problem, but after completely removing it's usage, the swipe still doesn't produce animation. So that's not the culprit.
I've gone so far as to try a different cell swipe implementation (TLSwipeForOptionsCell), but I get the same results of no action. I've also tried MCSwipeTableViewCell, which does work in showing the swipe action, but unfortunately presents it's own problems since it doesn't support auto-layout.
For the SWTableViewCell, I can confirm by stepping through the code that
The class receives the gesture and steps through the logic of the code appropriately.
The delegate methods are getting fired appropriately, so the control should have done what it was supposed to do.
However, nothing happens in my table view cell. No animation, no glitch/flicker, no sign that anything has changed.
I've also followed the guidance for using table view editing, which did remove the default "delete" option (desired to remove that anyway), but it still doesn't work.
As you can see in the documentation on GitHub, integrating this should be super simple, but it just doesn't work for me.
Target is iOS 7.1 SDK.
For SWTableViewCell (the swipe implementation I'd prefer to use), I've just noticed that the selection of the cell is lost almost immediately when starting to drag. If I touch and hold on the cell, it is selected. I move just slightly, and selection is lost. However, with MCSwipeTableViewCell the selection is not lost.
Any ideas?
At the expense of looking like an idiot, I'm going to log what the problem was just in case someone else makes the same mistake.
In addition to the symptoms above, I was also having a problem where touching on the cell so that the selection state was triggered would result in a highlight that covered all of my controls--the cell looked empty/blank. That was also resolved with the solution below.
In Interface Builder, I had set the backgroundView Outlet to contentView. Don't do that. Bad stuff happens.
Hope someone else ends up benefiting from this.
I have a UITableview that doesn't take up the whole screen (screenshot). Everything worked fine in iOS 6. But in iOS 7, when the user searches, the search result table takes up the whole view (screenshot).
To fix this, I tried setting the frame manually as described in this answer. The appearance is now correct (screenshot), but now the "<" button in the top left doesn't receive tap events when the search results table is displayed.
It seems the searchResultsTableView is adding a full-screen background view that is intercepting touch events. To prove this, I added this code to didShowSearchResultsTableView:
controller.searchResultsTableView.superview.backgroundColor = [UIColor blueColor];`
This screenshot confirms my hypothesis.
How can I fix this to allow the "<" button to receive tap events?
I want to avoid modifying controller.searchResultsTableView.superview so that my change doesn't break in future versions of iOS.
And what change in iOS 7 caused this behavior to start happening?
I am still searching for a better solution, but currently my solution is in the viewControllers viewDidLayoutSubviews tell your view to move to front. The code would look something like this.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.view bringSubviewToFront:self.navigationBar];
}
I have some simple code that moves the 'firstResponder' between UITextFields by calling 'becomeFirstResponder' on each field in turn.
In iOS 5, the keyboard is shown as constantly, until the final textfield where resignFirstResponder is shown.
However, in iOS 6, the keyboard performs the dismiss and reappear animation each time the first responder is moved. At no point do I call resignFirstResponder when calling becomeFirstResponder to move the responder (or in any of the associated methods) - it just seems to be new default behaviour in iOS 6.
This is distracting, and unwanted.
I've looked through the Apple documentation, and can't find any mention of a change to how the keyboard animation is managed.
Can anyone refer me to documentation of these changes? Thanks.
Found the problem.
My code was also calling,
[self.tableView reloadData];
...when calling becomeFirstResponder.
Therefore, the keyboard was being dismissed while the redraw occurred.
This certainly seems to cause different keyboard behaviour between iOS 5 & 6. Though the behaviour in 6 doesn't seem wholly unreasonable, considering.
Thanks to #Fogmeister for the help.
My app uses a UITableView with a UINavigationController to show a more detailed view when a row of the table is tapped - the basic drill-down routine.
When I tap on a row, it is highlighted, but the delegate methods tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath: are not called (verified using debugger).
Now here's the weird part:
There are some other table views in the app (they don't drill down) and none of them exhibit the issue.
If I tap the row rapidly and repeatedly, after many tries (10 - 20 is normal), tableView:willSelectRowAtIndexPath: and tableView:didSelectRowAtIndexPath: are called and processing continues normally.
The problem occurs only on an (any, actually) iPad running iOS 6. It works fine with iPads running iOS 5, or with any iPhone running any iOS version, 6. It also works with the iPad simulator using iOS 5 or 6.
So it seems that something is receiving the tap before the delegate methods are called. But what?
I not using any UITapGestureRecognizer, so that is not the issue.
I am not using multiple UITableViewControllers for the table, so this is also not the issue.
I was having this issue with an app when running in iOS6. The tableView:didSelectRowAtIndexPath: method was never being triggered, even though it was working before updating to iOS6.
I finally figured it out by looking at the xib and the attribute inspector for the table. In the Table View section I had the Selection option set to No Selection and Show Selection on Touch was not selected.
Changing the Selection option to Single Selection actually got this working for me again and leaving the Show Selection on Touch unselected means that I don't see any flash or change of colour when the row is selected.
I encountered a similar issue. iOS 6 appears to be much more sensitive to the slightest upward movement on a tap on a table view cell. It appears it is registering the slightest movement as a scroll request rather than a cell selection. My table view was set to scrollEnabled = NO because it is a table view with static selection values. The table view appears within a small area of a larger iPad view. If I carefully tap a cell and lift directly up, the cell is selected.
To resolve it, I changed scrollEnabled to YES and made sure the area dedicated to my tableView was larger than the actual area needed to show the table view, thus preventing it from scrolling. Not sure if this is is the cause of the issue you are experiencing, but hope it helps.
I had the same problem. The UITableView was not triggering the didSelectRowAtIndexPath method when running in iOS6, but it was working fine in iOS5.1.
I had also implemented the
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
return NO;
}
and returned NO. In iOS5 it was all working fine, but the minute I switched to iOS6 it would cease to trigger the didSelectRowAtIndexPath. Once I removed that shouldHighlightRow method, everything worked in iOS6 again. Cheers!
The usual reason that didSeletRowAtIndexPath() doesn't get called is having a UITapGestureRecognizer on your viewcontroller with Cancels touches in view set to YES.
The correct and only sensible fix is to set Cancels touches in view to NO. Then your table row selection should work nicely.
Obviously this has some implications in your gesture handlers - you may need to add some code to your gesture handler to stop some touches going on to your views i.e.
- (IBAction)onTapGesture:(UITapGestureRecognizer *)sender {
if (sender.view == someOldViewThatINeedToDealWith) {
sender.cancelsTouchesInView = true;
}
}
I tried all the other answers posted, and although they seemed promising, they didn't solve the problem.
I've since discovered the cause of problem in my case: I was calling [self.tableView reloadData] on a different thread (due to handling an NSNotification event posted from a background worker thread).
I fixed the problem by changing [self.tableView reloadData] to
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
Hope this helps.
The other suspect could be a Tap Gesture Recognizer set to the view controller's view swallowing all taps like a blackhole. Remove the gesture recognizer will enable did select. I just had the same issue and the tap gesture was the cause.
The resolution is really weird: the UITableViewController registered for all notifications. In the handler for the notifications, the table view data was being reloaded using
[self.tableView reloadData]
According to Apple DTS, when the table reloads data, this causes a notification to be sent to the observer, causing a race condition ...
No explanation for why it would work sometimes or why it would always work on an iPhone. But registering only for a small subset of notifications (i.e. the ones I was really interested in) fixed the problem!
Setting
recognizer.cancelsTouchesInView = NO;
takes care of it if your use case allows simultaneous handling
of touches by [tap] gesture recognizer (kdb dismiss for example)
and the view the recognizer is attached to.
in my case I hade button which received all touch events before tableviewcell