PresentViewController Custom Size & Centered in Xcode 5 and iOS 7 - ios

I have read through all of the solutions on here and still am having this issue. I have tried almost anything that I can think of or find.
We just updated to using Xcode 5.0.2 from Xcode 4.6.3 and the code from 4.6.3 worked with no issue. Currently my code looks like this. This is what used to work and I have come back to this because nothing else has worked either.
At this point the size is correct but its in the upper right corner of the screen.
I've also tried adding
actionViewController.View.Center = this.View.Center;
but it didn't change the centre. Any help is greatly appreciated. I'm going crazy at the moment :)
IStoryboard storyBoard = UIStoryboard.FromName ("WorkOrderActions_iPad", null);
VZWOActionViewController actionViewController = (VZWOActionViewController)storyBoard.InstantiateViewController ("VZWOActionViewController");
actionViewController.ModalPresentationStyle = UIModalPresentationStyle.PageSheet;
actionViewController.actionViewControllerID = actionViewControllerName;
this.PresentViewController (actionViewController, true, completionHandler: null);
if (actionViewController.View.Superview != null) {
actionViewController.View.Superview.AutoresizingMask = UIViewAutoresizing.FlexibleMargins;
actionViewController.View.Superview.Bounds = new RectangleF (0.0f,0.0f, 924.0f, 648.0f);
}

There is an issue in iOS 7, this can be fix only if you set transition to cross dissolve.
actionViewController.ModalTransitionStyle= UIModalTransitionStyleCrossDisolve

Related

Safe area layout guides in xib files - iOS 10

I started adapting my app for iPhone X and found an issue in Interface Builder.
The safe area layout guides are supposed to be backwards compatible, according to official Apple videos. I found that it works just fine in storyboards.
But in my XIB files, the safe area layout guides are not respected in iOS 10.
They work fine for the new OS version, but the iOS 10 devices seem to simply assume the safe area distance as zero (ignoring the status bar size).
Am I missing any required configuration? Is it an Xcode bug, and if so, any known workarounds?
Here is a screenshot of the issue in a test project (left iOS 10, right iOS 11):
There are some issues with safe area layout and backwards compatibility. See my comment over here.
You might be able to work around the issues with additional constraints like a 1000 priority >= 20.0 to superview.top and a 750 priority == safearea.top. If you always show a status bar, that should fix things.
A better approach may be to have separate storyboards/xibs for pre-iOS 11 and iOS-11 and up, especially if you run into more issues than this. The reason that's preferable is because pre-iOS 11 you should layout constraints to the top/bottom layout guides, but for iOS 11 you should lay them out to safe areas. Layout guides are gone. Laying out to layout guides for pre-iOS 11 is stylistically better than just offsetting by a min of 20 pixels, even though the results will be the same IFF you always show a status bar.
If you take this approach, you'll need to set each file to the correct deployment target that it will be used on (iOS 11, or something earlier) so that Xcode doesn't give you warnings and allows you to use layout guides or safe areas, depending. In your code, check for iOS 11 at runtime and then load the appropriate storyboard/xibs.
The downside of this approach is maintenance, (you'll have two sets of your view controllers to maintain and keep in sync), but once your app only supports iOS 11+ or Apple fixes the backward compatibility layout guide constraint generation, you can get rid of the pre-iOS 11 versions.
By the way, how are you displaying the controller that you're seeing this with? Is it just the root view controller or did you present it, or..? The issue I noticed has to do with pushing view controllers, so you may be hitting a different case.
Currently, backward compatibility doesn't work well.
My solution is to create 2 constraints in interface builder and remove one depending on the ios version you are using:
for ios 11: view.top == safe area.top
for earlier versions: view.top == superview.top + 20
Add them both as outlets as myConstraintSAFEAREA and myConstraintSUPERVIEW respectively. Then:
override func viewDidLoad() {
if #available(iOS 11.0, *) {
view.removeConstraint(myConstraintSUPERVIEW)
} else {
view.removeConstraint(myConstraintSAFEAREA)
}
}
For me, a simple fix for getting it to work on both versions was
if #available(iOS 11, *) {}
else {
self.edgesForExtendedLayout = []
}
From the documentation: "In iOS 10 and earlier, use this property to report which edges of your view controller extend underneath navigation bars or other system-provided views. ".
So setting them to an empty array makes sure the view controller does not extend underneath nav bars.
Docu is available here
I have combined some of the answers from this page into this, which works like a charm (only for top layout guide, as requested in the question):
Make sure to use safe area in your storyboard or xib file
Constraint your views to the safe areas
For each view which has a constraint attached to the SafeArea.top
Create an IBOutlet for the view
Create an IBOutler for the constraint
Inside the ViewController on viewDidLoad:
if (#available(iOS 11.0, *)) {}
else {
// For each view and constraint do:
[self.view.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor].active = YES;
self.constraint.active = NO;
}
Edit:
Here is the improved version I ended up using in our codebase. Simply copy/paste the code below and connect each view and constraints to their IBOutletCollection.
#property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *constraintsAttachedToSafeAreaTop;
#property (strong, nonatomic) IBOutletCollection(UIView) NSArray *viewsAttachedToSafeAreaTop;
if (#available(iOS 11.0, *)) {}
else {
for (UIView *viewAttachedToSafeAreaTop in self.viewsAttachedToSafeAreaTop) {
[viewAttachedToSafeAreaTop.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor].active = YES;
}
for (NSLayoutConstraint *constraintAttachedToSafeAreaTop in self.constraintsAttachedToSafeAreaTop) {
constraintAttachedToSafeAreaTop.active = NO;
}
}
The count of each IBOutletCollection should be equal. e.g. for each view
there should be its associated constraint
I ended up deleting the constraint to safe area which I had in my xib file.
Instead I made an outlet to the UIView in question, and from code I hooked it up like this, in viewDidLayoutSubviews.
let constraint = alert.viewContents.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 0)
constraint.priority = 998
constraint.isActive = true
This ties a small "alert" to top of screen but makes sure that the contents view within the alert is always below the top safe area(iOS11ish)/topLayoutGuide(iOS10ish)
Simple and a one-off solution. If something breaks, I'll be back 🙄.
This also works:
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 11.0, *) {}
else {
view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height - 80).isActive = true
view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width - 20).isActive = true
}
}
I added a NSLayoutConstraint subclass to fix this problem (IBAdjustableConstraint), with a #IBInspectable variable, looks like this.
class IBAdjustableConstraint: NSLayoutConstraint {
#IBInspectable var safeAreaAdjustedConstant: CGFloat = 0 {
didSet {
if OS.TenOrBelow {
constant += safeAreaAdjustedConstantLegacy
}
}
}
}
And OS.TenOrBelow
struct OS {
static let TenOrBelow = UIDevice.current.systemVersion.compare("10.9", options: NSString.CompareOptions.numeric) == ComparisonResult.orderedAscending
}
Just set that as the subclass of your constraint in IB and you will be able to make < iOS11 specific changes. Hope this helps someone.
I used this one, add the top safe area layout and connect with outlet
#IBOutlet weak var topConstraint : NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
if !DeviceType.IS_IPHONE_X {
if #available(iOS 11, *) {
}
else{
topConstraint.constant = 20
}
}
}
Found the simpliest solution - just disable safe area and use topLayoutGuide and bottomLayoutGuide + add fixes for iPhone X. Maybe it is not beautiful solution but requires as less efforts as possible

Navigation bar title and navigation buttons not appearing on iOS 11

Prior to iOS 11, the UINavigationBar buttons and title are being displayed correctly.
Yesterday I downloaded Xcode 9 with iOS 11 and, after building and running without doing changes, both navigation buttons and the title are not being displayed anymore. It shows the UINavigationBar with the correct color I am setting but nothing else.
I tried on different simulators and also I updated an iPhone 7 to iOS 11 beta 5 and the result is the same. Nothing being displayed.
Has someone faced the same problem? I have tried changing different parts of the code and storyboard but nothing affects...
EDIT with screenshots: http://imgur.com/a/Hy46c
Thanks in advance!
For Xcode 9, it appears that it is no longer enough to just set the frame of a custom view that is being injected into the navigationItem titleView. The intrinsic content size of your titleView now must be overriden and set as well.
Here's the code, adjust the width and height to suit your needs:
class NavigationBarTitleView: UIView {
override var intrinsicContentSize: CGSize {
return CGSize(width: bounds.width - 100, height: 50)
}
...
}
use sizeToFit()! ios 11 automatically sizes it, but ios 10 does not
I had the same issue and for me it was caused by subclassing UITabBarController
Did you set "window,rootViewController = ..." in your code ? Try remove it can fix your problem
I had the same problem in my project where the titles were missing from the navigation bars after updating to Xcode 9 and iOS 11. I solved it by going to the navigation bar of my navigation controller on the storyboard, keeping the Prefers Large Titles unchecked and changing the Title Font under Title Text attributes, which was set by default in Xcode 9 to System 0 to some other option like Caption 1 or Headline. I also changed its children viewcontrollers' navigation bar settings For Large Title to Never instead of Automatic or Always.
I found this code in some inherited codebase, commented it out and everything worked as it did before iOS 11.x.
if (appDelegate.window.rootViewController != self) {
appDelegate.window.rootViewController = self;
}
Try to use:
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
or without appearance proxy setting directly to the current navigationBar...It solves my problem, should Apple changed titleText to clear as default in iOS11...?
Also use this if you want the same look as iOS 10:
if #available(iOS 11, *) {
nav.navigationBar.prefersLargeTitles = false
}
Had the same issue with the navigationButton not displayed. I solved it by setting the renderingMode to .alwaysOriginal. (I didn't use templates)
Swift 3 code:
var img =R.image.smt()?.withRenderingMode(.alwaysOriginal)
I had that same issue and none of the above fixed.
Although, #Justin Vallely lead to me fix it.
All I did was to set a width on the titleView and everything worked just fine!
EDIT:
Every UIViewController has a navigationItem property, and every navigationItem has an optional titleView.
For reference: https://developer.apple.com/documentation/uikit/uinavigationitem/1624935-titleview
In my case, I was using a custom titleView and I think that's the cause of the problem, since Apple changed the API to support the new navigation bar layout.
Based on the Justin Vallely's comment I've reworked the code a little to ensure proper sizing of the view:
class NavigationBarTitleView: UIView {
private var width: CGFloat = 0.0
private var height: CGFloat = 0.0
override init(frame: CGRect) {
super.init(frame: frame)
width = frame.width
height = frame.height
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override var intrinsicContentSize: CGSize {
return CGSize(width: width, height: height)
}
}
In my particular case I've used this view as a container to UISearchBar and now it is well sized and worked perfectly with Swift 4 & iOS 11, just as it used to work on previous iOS & Swift versions
We were facing the same issue where the navigation bar color is there but the title and the buttons are not showing up. We have double checked the bar was there by triggering a navigation bar background color change 2 seconds after the navigation controller showed up on the screen, so we know the navigation bar was there and we were adding buttons to the correct instance. Same as the OP, this issue only appears on iOS 11 and not iOS 10, and we are using Swift 3.2 running Xcode 9.1.
After hours of fiddling around, it turns out that presenting a navigation controller, then making it as the UIApplication.shared.delegate.window.rootViewController (after the present animation) caused the issue in our case.
If you just skip the present view controller and make the navigation controller as the root view controller, then everything works fine. Of course, you lose the present animation in the case.

UITextView scroll bug iOS9 xcode 7.1.1

I have a simple UITextView that occupies all the screen.
When the text length is bigger than the Textview height, it automatically scrolls to the bottom (see image).
I have already tried
self.textView.scrollRangeToVisible(NSMakeRange(0, 0))
and
self.textView.scrollsToTop = true
and other things without any result.
I'm using iOS 9 with the latest swift and Xcode 7.1.1.
I've found a solution.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.textView.setContentOffset(CGPoint.zero, animated: false)
}
but I still don't understand why it didn't work.
You also try
self.textView.scrollRangeToVisible(NSRange(location:0, length:0))

"Auto Layout still required" error when adding subview to UITableView only on iOS 7

I have a container which loads an UITableViewController. On the beginning there is no data in the table so I show an empty view. This is how I do it in ViewDidLoad:
emptyView = new UIView ();
emptyView.BackgroundColor = UIColor.Gray;
// works on iOS 8 but has to be removed on iOS 7
emptyView.TranslatesAutoresizingMaskIntoConstraints = false;
var views = NSDictionary.FromObjectsAndKeys(
new object[] { emptyView },
new object[] { "emptyView" }
);
View.AddSubview (emptyView);
this.TableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;
View.AddConstraints(NSLayoutConstraint.FromVisualFormat ("V:|-0-[emptyView]-0-|", NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
View.AddConstraints(NSLayoutConstraint.FromVisualFormat ("H:|-0-[emptyView]-0-|", NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
The problem is now the line where I disable the autoresizing mask. On iOS 7.1 (on device and simulator) I get the following error:
NSInternalInconsistencyException Reason: Auto Layout still required
after executing -layoutSubviews. UITableView's implementation of
-layoutSubviews needs to call super.
If I comment out TranslatesAutoresizingMaskIntoConstraints everything works fine. The same code is running without modifications on iOS 8. I only remove the autoresizing mask on my view and not on the whole UITableView. Adding the view to the table header leads to the same problem.
How should I solve the problem with Auto Layout? Although the code is in C# you can always provide solutions from the Objective C world because the concepts are the same.
I moved away from auto layout and I'm not using it anymore for my emptyView.
emptyView = new UIView (new RectangleF(0, 0, this.View.Bounds.Size.Width, this.View.Bounds.Size.Height));
emptyView.BackgroundColor = UIColor.White;
emptyView.AutoresizingMask = UIViewAutoresizing.All;
Now it works, but I don't know if it is intended to not use auto layout. Perhaps one could provide a better answer which I could mark as accepted.

IOS 8 my UIScrollView doesn't scroll

I have an issue on iOS8 my textview doensn't scroll correctly like it used to be on all previous versions.
My code is this one :
const BOOL scrollToBottom = (chatTextView.text.length == 0);
chatTextView.text = getStr;
NSUInteger length = chatTextView.text.length;
if (scrollToBottom)
{
chatTextView.selectedRange = NSMakeRange(length, 0);
[chatTextView scrollRangeToVisible:chatTextView.selectedRange];
Do you have an idea were the problem might come from ?
In the previous ios version the scroll was always scrolling to bottom when there was new messages in the chatbox. Now the scroll view always refresh to somewhere in the middle of the chat box. I've tried quick hack like NSMakeRange(length+1000, 0); but it doens't change anything

Resources