In iOS 9 the uitableview footer text alignment/spacing changed, what can I do? - objective-c

Hei.
These two pictures below show what changed. Here's my code for it and the code didn't change.
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
if (section == 0) {
return #"If enabled, closing apps via the app switcher won't actually close the app itself.\n\nThis option is perfect to use with Fast Freeze.";
}
NSString *offDescription = #"OFF\nDisables the backgrounding capability completely. The app has to restart every time you close it.";
NSString *fastFreezeDescription = #"FAST FREEZE\nThis mode is similar to what 'Smart Close' by rpetrich did. Usually an app has up to 10 minutes to perform tasks in the background before it gets suspended in memory. Since this can be an unnecessary battery drain, Fast Freeze will suspend the app right after you close it.";
NSString *nativeDescription = #"NATIVE\nThis is Apple's built in way of backgrounding.";
NSString *unlimitedNativeDescription = #"UNLIMITED NATIVE\nThis background mode allows apps to execute background tasks for an unlimited period of time, so the app won't get suspended in memory after 10 minutes.";
NSString *foregroundDescription = #"FOREGROUND\nForeground tricks the system into thinking that the app wasn't closed and is still running in foreground. This is the perfect way to continue to listen to internet streams or videos while using another app.";
return [NSString stringWithFormat:#"\n%#\n\n%#\n\n%#\n\n%#\n\n%#", offDescription, fastFreezeDescription, nativeDescription, unlimitedNativeDescription, foregroundDescription];
}
Here are the screenshots:
This is the view before (iOS 8), notice that "\nOFF\nDisables ..." has the gap to the last UITableViewCell like it should be.
This is the view after (iOS 9), the gap is off. Too much space there.
So, does anyone know why this happens? If anyone has an fix or something, please tell me!
Thanks in advance!

This seems like an Apple's bug (iOS 9.0 - 9.1), the more lines footer has, the bigger misplacement gets.
You can even reproduce this in the storyboard using static table view.
I cound't find any workaround yet, the best advice I can give is to file a bug report to Apple.
Update
The bug in storyboard seems to be fixed in Xcode 7.2 beta 2. However this issue still persists when you run the app even on iOS 9.2 simulator.
Update 2
Narrowed down the reproduction of this bug. Basically something breaks after your app presents a table view section header. Check this repo for details.

Related

UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes: and viewWillAppear: order

a quick question for any of you who might have an idea:
I recently encounter a bug in on of my app, and that have raised a little question.
The bug was caused by a piece of code trying to access to an array not yet set.
The funny buisness here was that the same code worked absolutely fine on an iPad Air, and crashed on an iPad Pro.
Indeed, i was trying to access the array in the collectionView:cellForItemAtIndexPath: method of my controller, and the array was initialized in the viewWillAppear: method of the same controller.
In any device that i have tried, exepted on the iPad Pro, the collectionView:cellForItemAtIndexPath: method was always called after the viewWillAppear:, but on the iPad Pro, it is the other way.
I easily fixed the issue, but i'm still wondering why the iPad Pro have a different cycle than the other. Anyone have a clue about that?
(I'm on Objective-C, iOS 11.0)
Change the collectionView:cellForItemAtIndexPath method for conditions like following
if (array has data || data is downloading) {
show activity indicator
} else {
show data
}
Reload collection view when data loads

Display waiting screen when user selects UITable row

When the user selects a row in my table, I need to load a bunch of data with CoreData. This takes several seconds (at least when running on the simulator - haven't tested on a device yet, but I imagine it will still be pretty long). I want to display a loading popover screen (I'm developing for iPad) when the user selects a row, then have it disappear once the data is loaded.
When working with UIButtons, I've always done this by triggering both a TouchDown and TouchUp method. I put the code to display the popover on the TouchDown, then do all my actual work (so in this case loading from CoreData) in the TouchUp. Then at the end of TouchUp, I close the popover.
Is there a way to split up touches in a table view the same way as ones on a button?
So while I was typing up the question I came across something in the Apple Docs for willSelectRowAtIndexPath and it looks like that is there to address this very issue. I didn't see any other topics on this on SO, so I figured I'd make use of this "Answer own question - Q&A" feature on here, so maybe people looking for this in the future will find it a little easier.
Huge FYI block:
I should note that willSelectRowAtIndexPath is actually supposed to return an NSIndexPath, unlike didSelectRowAtIndexPath (which returns void). However, I originally had
-(void)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//stuff
}
Note the void return type. Xcode (Version 4.5) allowed this without any errors or warnings (and even had it for me in the autocomplete list). When I ran the code this way, I always hit an invisible breakpoint in libobjc.A.dylib'objc_autorelease: (maybe becaues I have the "All Exceptions" breakpoint enabled?). I couldn't get past this breakpoint, I never got any debug information in the debugger output console, and the app never terminated. I happened to look at the Apple Doc again and notice that it was supposed to return an NSIndexPath (specifically, the index path the code should interpret as being the one that was selected), but if I didn't happen to see it there, I never would have known what the problem was.

EAAcessory errors while closing session with iOS 6.0 GM

There is a MFI device that is connected to iPhone 4S (6.0 GM) or to iPad (6.0 GM) via Bluetooth (2.1 + EDR). The project was built on Xcode 4.5 GM. When the app gets EAAccessoryDidDisconnectNotification it will send message [_eaSessionController closeSession];. All these worked nice in iOS 5.1.1 or earler. But on iOS6 with this message I got logs as follows:
-[NSCondition dealloc]: condition (<NSCondition: 0x2e5640> '(null)') deallocated while still in use
Break on _NSLockError() to debug.
Any ideas?
I came across the same issue. This warning is thrown when calling [NSStream close] upon receiving an EAAccessoryDidDisconnectNotification. There should be also some data exchange between the two devices just before the disconnection.
Breaking on _NSLockError will show that at the moment the object is deallocated, some of the threads spawned by the external accessory framework are waiting on conditions. One of those certainly waits on the condition that is being freed, which explains the warning thrown on the console.
I also noticed that the number of threads created by the external accessory framework keeps on growing each time the accessory disconnects then connects, and they seem to be just leaking.
It seems to me that somehow, the external accessory framework does not properly free the resources it allocates, which results in a lot of mess. One of the subsequent effects of this are crashes that happen inside one of those leaked threads during a call to OSAtomicCompareAndSwap64.
I managed to reproduce the issue using a basic sample in which the streams are scheduled on the main thread to avoid any thread management inside the application. I believe it's an accessory management bug on iOS 6 that Apple should be aware of. I'll report it and wait for what they have to say.
Meanwhile, I wonder if anyone of you guys has managed to make any progress on this.
Thanks,
There is no such trouble in iOS 6.1+. To fix this for iOS 6.0 and iOS 6.0.1 please use next solution:
Please note: this is only temp solution allow your users with iOS 6.0 and 6.0.1 continue use your app.
There is a simple hack to avoid application crashes: just create new category and override dealloc method (NSCondition) for iOS 6.0 and iOS 6.0.1:
#import "NSCondition+LeakDealloc.h"
#import <objc/runtime.h>
#implementation NSCondition (LeakDealloc)
- (void) safeDealloc
{
float sVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (sVersion < 6.0 || sVersion >= 6.1)
{
[self safeDealloc];
}
}
+ (void) load
{
method_exchangeImplementations(class_getInstanceMethod(self, #selector(dealloc)), class_getInstanceMethod(self, #selector(safeDealloc)));
}
#end
This solution make new leak, after 20 min tests and about 50 BG/FG swithces instruments shows 10 NSCondition leaks (960 Bytes), BUT no one crash!
The issue has been fixed in iOS 6.1.
There are no more leaking NSCondition or external accessory threads. Apple seem to having fixed the issue properly.

Facebook Connect Login Dialog crashing app

Of the many problems I've been having with my current app, this is one of the most annoying.
In the simulator the login dialog works fine, however on a device it's just a frozen white box and the console prints the following:
void SendDelegateMessage(NSInvocation*): delegate
(webView:resource:willSendRequest:redirectResponse:fromDataSource:)
failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
I've looked this up but I'm still not sure what it means.
If I try switching
[self authorizeWithFBAppAuth:NO safariAuth:NO];
to
[self authorizeWithFBAppAuth:NO safariAuth:YES];
it switches to the safari app to verify but this somehow kills my app with an error which says ReturnNotPermittedKillClient.
Has anyone experienced a similar problem? On my last app it just worked without any of these issues, and as far as I can see I've done everything the same way this time. However this project was inherited from someone else so there may be underlying causes that I am not aware of.
Edit: Just tried moving the login request from didFinishLaunchingWithOptions to a point in the intro screen class where everything else has already been loaded, just in case it was a memory issue caused by too many tasks trying to run at the same time. This time the error message didn't appear, however the login box still remained white and then closed the app a few seconds later.
Edit2: Seems like it's simply a memory error. I changed all variables which I had previously released to be retained, which has fixed the problem on my 3GS. However on my iPad 1 the problem persists. Incidentally, when changing shouldAutorotateToInterfaceOrientation from using landscaperight to using landscaperight or landscapeleft, when I rotate the iPad I get a memory warning and then the same crash. In both cases there are no debug error messages other than the memory warning, and the app just closes down - there is no breakpoint etc to see where the issue lies.
if you are using the webview then we need to do this first b4 moving to next view .delegate = nil;
This might be what you want:
There are other branches of this in NSObject in the documentation.
Code:
[self performSelector: withObject: afterDelay: ]
The problem was simply down to memory. After changing the way it loads images, sounds etc the problem has gone away.

Problem: restarting App

My App is a view-based application. At the beginning I show my logo and after a delay of a few seconds it changes into another view. from then on the user can switch to a lot of different views.
Sooooo.. My Problem: The thing is, when I restart my App. [..well closing and reopen by touching the icon..] the app itself doesnt restart in the sence of jumping to the very first view. to the contrary: at restart the user just returns to the last view that was open.
So I dont know why this is.
Is it normal to somehow manually tell the app to return to the very first view after restart? And if so, how do I have to do that?
PS.
I have so no idea what to do.. Maybe my problem has to do with the timer i used in the first view to change after a delay of time?
Please, is there anyone, who can help me?
Your problem is that, as of iPhone 4, returning to the home screen does not terminate your app. It's just made inactive, so opening it again reactivates it. In most cases, this is a good thing. If it doesn't work for your app, you can add the UIApplicationExitsOnSuspend key to your Info.plist with a value of YES.
(As I said, you should only do this if it really helps usability. If it's just about getting your splash screen shown again, most users and possibly Apple will frown upon it.)
iOS 4.0 and greater have a fast-start thing that allows apps to restart back from where they were upon restarting. There are several ways to deal with this:
1.) your App Delegate receives info about being but into the background and resumed. - (void)applicationDidBecomeActive:(UIApplication *)application and - (void)applicationDidEnterBackground:(UIApplication *)application are the relevant functions here. Check the docs.
2.) You can also disable the background, inactive state completely by including UIApplicationExitsOnSuspend in you Info.plist as Chuck already pointed out.
Overall, you should check the application state docs on Apple's Side.