I have UITextView that I would like to make the same height and width of it's container. It is in a simple UIViewContainer.
I tried doing the following:
override public func viewDidLoad() {
self.edgesForExtendedLayout = .None
resultText.text = result
resultText.frame = view.frame
}
This seems to work for portrait but not landscape.
All I am trying to do is make the UITextView take up all the space of it's container.
If I could find the answer in Objective-C I could easily translate it to Swift. I am just looking for the answer for iOS.
I suggest you to use auto layout
Then click add 4 constraints.
If any warning,
Click Update Frames
Autolayout is your friend - It can be done easily using Interface Builder, or in code:
override public func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = .None
resultText.text = result
// add vertical constraints to pin the view to the superview edge
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0.0-[resultText]-0.0-|", options: nil, metrics: nil, views: ["resultText": resultText]))
// add horizontal constrains to pin the view to the superview edge
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0.0-[resultText]-0.0-|", options: nil, metrics: nil, views: ["resultText": resultText]))
}
Related
I've created an xib and loaded the nib in my viewDidLayOutSubviews:
I then added the subview:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if (myCustomView == nil) {
myCustomView = Bundle.main.loadNibNamed("Help", owner: self, options: nil)?.first as? HelpView
self.view.addSubview(myCustomView!)
}
}
My constraints are all set up correctly in my xib (toggling between devices look okay), however when I launch the app on a different device the autolayout is not updated. How do I fix this? Thank you!
Edit:
Toggled for iPhone 7, but launching for iPhone 7 Plus
Toggled for iPhone 7 Plus, launching for iPhone 7 Plus
Your constraints may be setup correctly in your nib, but you don't have any constraints when you call self.view.addSubview(myCustomView!), so the frame is just going to be whatever it is in the nib file. You need to constraint myCustomView to self.view. Give it equal width, center X, equal top and a fixed height (or use the intrinsic height) and it should be fine. Make sure you turn off translatesAutoresizingMaskIntoConstraints.
just add this line below
self.view.addSubview(myCustomView!)
myCustomView.translatesAutoresizingMaskIntoConstraints = false;
//Views to add constraints to
let views = Dictionary(dictionaryLiteral: ("myCustomView",myCustomView))
//Horizontal constraints
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|[myCustomView]|", options: nil, metrics: nil, views: views)
self.view.addConstraints(horizontalConstraints)
//Vertical constraints
let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|[myCustomView(SpecifyFixedHeight)]|", options: nil, metrics: nil, views: views)
self.view.addConstraints(verticalConstraints)
I try to use auto layout programmatically by visual format language on a view which is on storyboard but failed. The code is as below:
(Btw, the storyboard which shows bView is not important, so I didn't upload storyboard's picture. And I didn't setup any constrain on storyboard.)
class ViewController: UIViewController {
#IBOutlet var bView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
bView.translatesAutoresizingMaskIntoConstraints = false
var allConstraints = [NSLayoutConstraint]()
let vC = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
let hC = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
allConstraints += vC
allConstraints += hC
NSLayoutConstraint.activateConstraints(allConstraints)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
}
}
But when it executes, it shows error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint
format: Unable to interpret '|' character, because the related view
doesn't have a superview V:|-[bView]-|
^'
I guess maybe the superView (the view of the viewController) did add on the mainWindow. So I tried to fix this problem by moving the code to viewWillLayoutSubviews(). As Below:
class ViewController: UIViewController {
#IBOutlet var bView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
bView.translatesAutoresizingMaskIntoConstraints = false
var allConstraints = [NSLayoutConstraint]()
let vC = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
let hC = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
allConstraints += vC
allConstraints += hC
NSLayoutConstraint.activateConstraints(allConstraints)
}
}
Then it shows a really funny wrong result.
So, how do I layout a view which is on storyboard programmatically?
What's more, there's a funny result like this:
(It's not related to the question directly, but you can try it for fun!)
With code:
class ViewController: UIViewController {
#IBOutlet var bView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
bView.translatesAutoresizingMaskIntoConstraints = false
}
}
If you are trying to constrain the blue rectangle, then your first problem is that your bView outlet is incorrectly wired to your top level view (the white background). Delete that connection in the Connections Inspector and then wire the blue view to bView.
If you add a view in Interface Builder, but don't give it any constraints, then Xcode will add 4 constraints at build time. If you click on your view, you will see the following message in the Size Inspector:
The selected views have no constraints. At build time, explicit left,
top, width, and height constraints will be generated for the view.
So, your view is already fully specified. If you add any more constraints in code you will have conflicts.
So, how can you add constraints in code for a view laid out in the Storyboard? You need to do the following:
Add explicit constraints in the Storyboard for left, top, width, and height.
Edit these 4 constraints in the Size Inspector and check the box next to Placeholder [] Remove at build time.
Then, these 4 constraints will be removed at build time leaving the view without constraints. Now your code is free to add constraints.
I am trying to build a custom-looking action sheet. I thought the easiest way would be creating a view as a subview and assign constraint of subview's top to superview's bottom. And at the same time assigning a cover view with some opacity. Thus, I could have different versions of subview and I can initialise the necessary one and slide it.
I couldn't find anything useful for Swift, so, using this obj-c answer, I tried to convert it to Swift. I achieved the opaque background with this however translating constraints doesn't seem to work.
var coverView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
coverView.backgroundColor = UIColor(white: 0.0, alpha: 0.4)
coverView.alpha = 1.0
self.view.addSubview(coverView)
self.view.bringSubviewToFront(coverView)
}
//doesn't work
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[coverView]|", options: kNilOptions, metrics: nil, views: NSDictionaryOfVariableBindings(coverView)))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[coverView]|", options: kNilOptions, metrics: nil, views: NSDictionaryOfVariableBindings(coverView)))
I got confused on instantiating the view and applying transition animation. If I choose to create a UIView under ViewController, I cannot adjust constraints to adjust equal width of subview to superview.
How can I use the UIView that I created as a Subview (in Storyboard) and then adjust its width constraints so the UI doesn't bug? Also, how can I apply the transition animation so it seems natural?
This link should be here...
I suggested you use UIView xib file and design your view then load in your view controller.
Ex:
Step 1:
Create xib for view
Step 2:
Set background color black for this view, opacity 62% and Alpha = 1
Step 3:
Take new simple UIView and Design your actual view and set constraint.
For Exp:
In your case set view in bottom.
Step 4:
Load xib in view controller.
class calendarViewController: UIViewController
{
var popUpView: popUpView!
override func viewDidLoad() {
super.viewDidLoad()
bookingConfirmView = NSBundle.mainBundle().loadNibNamed("popUpView", owner: self, options: nil).first as! popUpView
// Set Delegate for xib textField
self.popUpView.Name.delegate = self
self.popUpView.MobileNo.delegate = self
}
}
Step 5:
Add this line to where you want to populate view.
self.view.addSubview(bookingConfirmView)
self.bookingConfirmView.frame = self.view.bounds
I recently added a scrollview to my viewcontroller. However, this caused my layout to mess up completely.
Here's an image below.
(I gave the UIScrollView a temporary red background, to display, that it's clearly taking the full screen)
now. I have a bunch of things in this view. But to keep it simple I will focus on the top blue bar, which in my app is called "topBar"
First of, I define it in my class.
var topBar = UIView()
I remove the auto sizing, give it a color and add it to my scrollview.
//----------------- topBar ---------------//
topBar.setTranslatesAutoresizingMaskIntoConstraints(false)
topBar.backgroundColor = UIColor.formulaBlueColor()
self.scrollView.addSubview(topBar)
add it to my viewsDictionary:
var viewsDictionary = [ "topBar":topBar]
add the height to my metricsDictionary:
let metricsDictionary = ["topBarHeight":6]
set the height in a sizing constraint.
//sizing constraints
self.scrollView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:[topBar(topBarHeight)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary))
And finally the part that doesn't work. I /attempt/ to make it the full width of "scrollView"
// Horizontal Constraints
self.scrollView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"H:|[topBar]|", options: nil, metrics: nil, views: viewsDictionary))
and my vertical constraint to put it at the top.
// Vertical Constraints
self.scrollView.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]", options: nil, metrics: nil, views: viewsDictionary))
Now as for my scrollview, (the one that's probably causing my layout headaches)
It's set up as follows:
as the very first thing in the class:
let scrollView = UIScrollView(frame: UIScreen.mainScreen().bounds)
first thing in my viewDidLoad()
self.view.addSubview(scrollView)
scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
scrollView.scrollEnabled = true
and lastly my viewDidLayoutSubviews.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
scrollView.contentSize = CGSize(width:2000, height: 5678)
}
^ The width of the contentSize will be changed to the width of the screen (I only want vertical scrolling). But right now that's a minor issue compared to the layout problems I'm having
Any help as to why everything is squeezed together would be greatly appreciated!
I managed to fix it doing the following.
Defining my contentsize in viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
scrollView.contentSize = CGSize(width:self.view.bounds.width, height: 5678)
}
and instead of making the view equal to a scrollview, I had to make it a subview of it.
I also had to make a subview of the scrollview, for all my content to work with constraints properly.
self.view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(contentView)
and all my other objects was made subviews of the "contentView" and not the scrollview.
How do you get the width and height of a UIView who's size and position are set using Auto Layout and Apple's Visual Format Language?
Here's the code (view is just the variable from UIViewController):
// Create and add the view
var stageView = UIView()
stageView.setTranslatesAutoresizingMaskIntoConstraints(false) // Since I'm using Auto Layout I turn this off
view.addSubview(stageView)
// Create and add constraints to the containing view
let viewsDictionary = ["stageView":stageView]
let horizontalConstraints: NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-150-[stageView]-150-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
let verticalConstraints: NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-100-[stageView]-150-|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: viewsDictionary)
view.addConstraints(horizontalConstraints)
view.addConstraints(verticalConstraints)
println("stageView.frame=\(stageView.frame)")
and got:
stageView.frame=(0.0,0.0,0.0,0.0)
so I tried:
let fittingSize = stageView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
println("fittingSize=\(fittingSize)")
and got:
fittingSize=(0.0,0.0)
I can't seem to find a way to get the size. I'm able to add subviews to stageView that place just fine using Auto Layout and Visual Format Language, but I can't get width and height for stageView which I need to further position those subviews.
Any ideas?
You have a few options:
You can force the layout engine to size the views immediately by calling setNeedsLayout and then call layoutIfNeeded. This is not recommended because it's inefficient and any manual frames required for layout might not have been set yet. You can read more about this approach on my answer to this question.
You can also wait until the subviews have been updated in the view controller:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
println("stageView.frame = \(stageView.frame)")
}
If you want to know within a UIView subclass (or more often, a UITableViewCell subclass, you can check after layoutSubviews has run:
override func layoutSubviews() {
super.layoutSubviews()
println("self.frame = \(self.frame)")
}
You need to check the frame inside viewDidLayoutSubviews.
This function run after constraint calculation
Its suppose to look something like this
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
//Print frame here
}