UIPopover with UIDatePicker throws exception in iOS5.1 - xcode

I have an enterprise iPad app that runs on several iPads of different vintage. All work fine except for one which is the only 1st generation iPad in the group. This iPad is running iOS 5.1.1. The app uses a UIPopoverController in several places and all work fine on this iPad except for the one that I last created.
Using the iPad 5.1 Simulator I was able to duplicate the problems…
The app crashes when trying to open a UIPopoverController which contains a UIViewController contining a UIDatePicker and a UIButton. The exception reads…
* Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named NSLayoutConstraint'
Here is the code I am using up to the line that throws the exception…
DatePickerPopOverViewController *datePickerViewController =[[DatePickerPopOverViewController alloc] init];
datePickerViewController.defaultDate = lastPopoverDate;
datePickerViewController.buttonTitle = #"Get Schedule";
datePickerViewController.delegate = self;
UIPopoverController *datePickerPopOver = [[UIPopoverController alloc] initWithContentViewController:datePickerViewController];
I am pretty sure that all of the elemnts involved are available in iOS5.1. Any suggestions would be greatly appreciated.
John

You can not use autolayout below iOS 6.0. The exception you are seeing is a result of this. NSLayoutConstraint is the class used to define interface element relationships when using autolayout.
To continue to target versions below iOS 6.0, simply uncheck "Use Autolayout" in the IB interface.

Related

Backwards compatibility of new NSSearchToolbarItem

With macOS 11 Apple has introduced a new NSToolbarItem called NSSearchToolbarItem that automatically resizes to accommodate typing when the focus switches to the toolbar item.
Here Apple says this is backwards compatible with older versions of macOS: https://developer.apple.com/wwdc20/10104 (minute 11:50)
However launching my app with a NSSearchToolbarItem from interface builder on macOS 10.13 (High Sierra), crashes my app with the following Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '***
-[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (NSSearchToolbarItem) for key (NS.objects); the class may be
defined in source code or a library that is not linked' terminating
with uncaught exception of type NSException
Launching it on 10.15 works fine. I haven't been able to test 10.14 yet.
Update 6 July 21 by Thomas Tempelmann
It turns out that this was a bug with older Xcode 12 versions and is now fixed in Xcode 12.5.1.
I had opened a bounty, because I had a seemingly related issue with the improper sizing of NSSegmentedControls inside the toolbar when running on High Sierra, but it turns out that this is a separate issue (which can be fixed by manually resetting the toolbar's minSize and maxSize to the control's frame.size).
Therefore, the solution is to use Xcode 12.5.1 or later.
Adding the item in storyboard without any code works properly, I have just tested. So probably you have done something wrong in the code. Or it is fixed in the latest XCode.
What I have found thus far is that this works only on Catalina, even on Mojave it crashes. According to #ThomasTempelmann it is better in XCode 12.5.1, but I haven't tested that yet.
There are two ways to solve this:
1. Use Xcode 12.5.1 or later
Build the app with Xcode 12.5.1 or later, wnhich appears to have fixed the compatibility with pre-10.14 systems.
2. Add the NSSearchToolbarItem in code
If you want to still be able to open the project with older Xcode versions (ie. Xcode 11 and earlier), you cannot place the new NSSearchToolbarItem into the storyboard, or older Xcode versions will refuse to open it.
In this case, you'd keep using the classic NSToolbarItem with an NSSearchField control inside it. The challenge is to replace it with an NSSearchToolbarItem when running macOS 11 or later.
I've tried several methods, such as explicitly removing the classic search toolbar item from the toolbar and then adding the new one, and implementing the delegate function to provide it. While that worked, it caused trouble when letting the user customize the toolbar: Then the dialog would keep showing the old search item along with the new one. The only way to resolve this was to access private functions (_setAllowedItems and _setDefaultItems), but I wasn't happy with that.
I finally found this fairly solution:
Create a new custom class, let's name it SmartSearchToolbarItem, and make it a subclass of NSToolbarItem.
In the storyboard, change the class of the Search Field from NSToolbarItem to SmartSearchToolbarItem.
Add the following code to the SmartSearchToolbarItem implementation:
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101600
#interface NSSearchToolbarItem : NSObject
- (instancetype)initWithItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier;
#end
#endif
#implementation SmartSearchToolbarItem
-(instancetype)initWithItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier
{
self = [super initWithItemIdentifier:itemIdentifier]; // this is necessary even if we won't use it, or we'll crash in Big Sur
Class cls = NSClassFromString(#"NSSearchToolbarItem");
if (cls) {
self = (id) [[cls alloc] initWithItemIdentifier:itemIdentifier];
}
return self;
}
Not only will this automagically replace the classic search item with the new one in Big Sur and later, it will even – and that's the part I don't really understand – still work with connected IBActions and IBOutlets. So, there's no need to copy and properties in code.
Fixing Segmented Controls
And if you happen to have segmented controls in your toolbar, then you'll also need this code to adjust their sizes as placement, as they have different widths on Big Sur vs. earlier macOS systems (10.15 and 10.14 will be fine, but if you also support 10.13, you will need this definitely):
- (void)fixSegmentedToolbarItemWidths // call this from `viewWillAppear`
{
if (#available(macOS 10.14, *)) {
// no need to set the sizes here
} else {
BOOL didChange = NO;
for (NSToolbarItem *item in self.view.window.toolbar.items) {
NSControl *control = (NSControl*)item.view;
if ([control isKindOfClass:NSSegmentedControl.class]) {
[control sizeToFit];
NSRect frame = control.frame;
const int padding = 2;
item.minSize = NSMakeSize(frame.size.width+padding, item.minSize.height);
item.maxSize = item.minSize;
didChange = YES;
}
}
if (didChange) {
[self.view.window.toolbar validateVisibleItems];
}
}
}
Sample code
Github page

MKMapView not Rendering in iOS 8 or later

I'm having an issue in MKMapView in iOS 8.x.x. Application works fine iOS 7.x.x but not in iOS 8.x.x. On device it shows only annotations but no map behind.
I tried to forcefully Reset my Device as well but no luck.
I added these 2 Values in info.plist as well as it was a requirement for iOS 8 and onwards
<key>NSLocationAlwaysUsageDescription</key>
<string>Location is required to find out where you are</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location is required to find out where you are</string>
and added this lines of code in my Viewdidload.
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
//[self.locationManager requestAlwaysAuthorization];
self.myMapView.showsUserLocation = YES;
}
By adding these 2 values in info.plist and the above lines of code, I'm able to get the User's Location and annotation in showing on map for user's location but Map is Blank.
Similar to this post:
MKMapView showing blank screen in iOS 8
Had the very same thing on IOS8.3 both sim and device.
Solved by running the system Maps App (it displayed empty grid as well) for a minute till it downloaded maps. After that my MKMapView started rendering as normal.
try add the delegate methods: - (void)mapViewWillStartLoadingMap:(MKMapView *)mapView;
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView;
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error;
and check the solution for you error message.
also check this solution i don't got rid of the grind but at least i got rid of the didFail error.
but seems to be an issue of iOS8 because on iOS8.3 works fine the same code.

InputAccessoryView does not show on iOS 8 simulator

I have iOS application since iOS 5, it includes a custom UITextView which use its own inputView and inputAccessoryView. It works with iOS 7 simulator, when it becomeFirstResponse, both inputView and inputAccessoryView show, but with iOS 8 simulator, only associated inputView shows, the inputAccessoryView does not show.
I am using Xcode 6 GM seed
HeInput_TextView.m
- (void)awakeFromNib
{
self.text = #"";
heKeyboard4x5 = [[HeKeyboard_ViewController alloc] init];
inputAccessoryVC = [[InputAccessory_ViewController alloc] init];
self.inputView = heKeyboard4x5.view;
self.inputAccessoryView = inputAccessoryVC.view;
}
Is it a bug in iOS 8 simulator or a change for iOS 8?
Edit:
I found more information about this problem.
This problem happens in Page-Based application, if an UITextView in a page of UIPageViewController, then the UITextView.inputAccessoryView doesn't show at iOS 8 simulator, but shows in iOS 7.1 simulator.
I creates two projects: 'Single-View Based application' and 'Page-Based application', and confirmed the problem happens as described above.
it is new behaviour of simulators in xcode 6. to see your custom accessory view or even default one try to uncheck hardware -> simulator -> connect harware keyboard.
It's an iOS8 bug.
You can reproduce it on the simulator in Apple's Contacts App.
Add a new contact and scroll down to "add a date".
Same problem. A colleague has raised an apple rdar.
I've found view accessories in iOS8 don't use the view's frame to offset their height above your InputView (or even the default software keyboard).
You might need to make sure your inputAccessoryView implements
-(CGSize)intrinsicContentSize
eg:
#implementation InputAccessory_View
// .. your code ...
-(CGSize)intrinsicContentSize{
return self.frame.size;
}
#end
My apologies, I misread the item. I've been driven batty by iOS8's keyboard issues.

Could not instantiate class named UIRefreshControl Xcode

I am building a RSS feed on a tableview. When i run the app, on my iPhone could run smoothly while in ipad, it crashed and showed "Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named UIRefreshControl'"
I tried to run the app on my ipad simulator, it also could run smoothly. May I know what is the problem for that?
Thanks
UIRefreshControl only exists on iOS 6. So if your iPad is running 5.1.1, you won't be able to use UIRefreshControl, because UIRefreshControl did not exist in iOS 5.1.1. So when the nib decoding happens, the decoder finds "UIRefreshControl", it doesn't know what to do with it, and it crashes.
In your storyboard, click on the tableview and go to the Attribute Inspector. Under the section "TableView Controller" there is a selection window for "Refreshing" that can be set to disabled. When I built for my iPad-1, running iOS 5.1 I got an empty tableView instead of the error, 'Could not instantiate class named UIRefreshControl'. This was to be expected since I haven't populated the device with files to select, yet.

iOS 6 navigation - do I have to use storyboards?

I have an app that is working fine for iOS 5, I've just installed the iOS 6 simulator and my navigation is no longer working at all. Also my viewWillAppear and viewDidAppear methods are no longer firing.
I'm using [self.navigationController pushViewController:vc animated:YES]; to navigate. Do I have to use StoryBoards to navigate in iOS 6?
Thanks
No, Storyboards are optional and have been around since iOS 5.0. If your navigation is broken it'll be due to errors in your code.

Resources