how to get calculated frames in custom UIView with auto layout - swift

I created a custom UIView based on a xib file and added some UIVIews with constraints.
In my View Controller I added a UIView and set the class to my custom view. So far so good. My custom View is displayed properly.
But now I do have a #IBInspectable (numerOfButtons: Int) and based on this number I want to add UIButtons programmatically to my custom view.
My problem is now, that I want to align this buttons to a subview in my custom view. So I try to set my button frames programmatically. But when I do this in layoutSubviews() my subviews are not calculated based of my auto layout constraints. I tried to call setNeedsLayout() and layoutIfNeeded() of my subview but this does not work.
How can I get the correct frames of my subviews (with calculation of my constraints) to work with them in layoutSubviews()
Or what do I wrong?
By the way. It seems that my approach does not works only if I try to run with iPad Pro 9.7 inch simulator?!

To set constraint programmatically will be time consuming thing but luckily we have an alternative solution with this library very easy to set constraint
let box = UIView()
self.view.addSubview(box)
box.snp.makeConstraints { (make) -> Void in
make.width.height.equalTo(50)
make.center.equalTo(self.view)
}
Hope this will help you

Related

Touch detection problems with custom View inside UIView NOT UIScrollView

I was googling for a while and I found similar problems but when the custom View is inside a ScrollView, but that is not my case.
I have a custom view that consists of a UILabel behind a UITextField, so I can animate that label later.
The problem is that when I add a View in my ViewController and in the Identity Inspector I set the Class as my custom class, when I use the application the UITextField within my custom view does not receive the touches well and it takes time to gain focus and therefore to open the keyboard. The strange thing is that if I move that same arrangement of views to my main ViewController in Storyboard everything works fine. Why doesn't it do it when I place it using the described method?
I plans to reuse this custom view a lot, so putting logic and views in each ViewController is not an option.
Thanks in advance
Well, the problem was in the constraints of the container UIView. That means, the UIView in my main ViewController. The Height of the UIView was a little bit smaller than the space required for my custom view, so although my custom view seemed to draw correctly, it was not receiving the gestures correctly. The solution was simply increase the height to the correct value occupied by my custom View. Thanks a lot!

UIStackView Weight like Linear layout

How to design the following layout with StackView
I know that it can be easily created without using stackview but is it possible using stackview because i have lots of ui which already designed using stackview how can i add divider between views like above image
For that i set the following constraints
**But run time it shows like **
You can use some simple Autolayout constraints to get this kind of interface with a UIStackView.
The below image describe the hierarchy and constraints that you can apply:
Also the Accept and Reject buttons have Equal Width constraint.
Output screenshot:
You can do that using UIStackViews, here is how:
First, create a subclass of UIView to use as the class of the UIView in between the 2 buttons.
class CustomWidthView: UIView {
override var intrinsicContentSize: CGSize {
return CGSize(width: 1, height: self.frame.height)
}
}
You only need to override intrinsicContentSize.
Now, add your 2 buttons and an empty UIView between them, and set the class of the UIView to be CustomWidthView. Embed your 2 buttons and the view between them in a stack view, and set the position of the stack view properly using the appropriate constraints.
Select the stack view and from Attributes inspector, find the property named Distribution and from the drop down menu next to it, select Fill Proportionally.
To reflect your changes in the UI Builder, select the custom width view and go to Size inspector, go down to the bottom of the list and you'll find a property called Intrinsic Size, change its value to be Placeholder, and from the width drop down menu, select 1.
There may be a better way to achieve this, but this is the one I found for now and I'd like to find a better one.
Since UIStackView uses auto layout to arrange its subviews, you can modify its behavior by creating constraints.
I assume you have three views in the stack: the accept button, the divider, and the cancel button.
Create two constraints:
An equal-width constraint between the accept button and the cancel button.
A fixed-width constraint on the divider (presumably setting its width to 1).
See also this Q&A.

Programmatically adding InterfaceBuilder-created views to an NSStackView squashes them to 0 height

I've been trying to add a custom view I've created in Interface Builder to an NSStackView, but am failing miserably.
This is my view controller. It currently does nothing but initialize the view from the NIB:
class ServiceControlViewController : NSViewController {
init() {
super.init(nibName: "ServiceControlView", bundle: nil)!
}
}
And here's how I'm trying to add the newly created view to the stack view (this happens in the app delegate):
#IBOutlet weak var stackView: NSStackView!
#IBAction func addButtonClicked(sender: AnyObject) {
let viewController = ServiceControlViewController()
stackView.addView(viewController.view, in: .top)
stackView.layoutSubtreeIfNeeded()
}
When I print the frame of the created view before it is added to the stack view it has the correct size. If I print it after, it is squashed to zero height. I suspect there is some auto-resizing magic going on that I don't understand, but I haven't been able to fix it.
Interestingly enough, if I set the ServiceControlViewController's view to e.g. be an NSButton, then it is correctly added and not squashed to zero height. It only happens with the Custom Views I create.
PS: My InterfaceBuilder-created view simply contains a bunch of buttons and a label:
PPS: I've added an MWE
It seems like there are no constraints on that custom view to make it larger than zero size.
You'll have to determine what its sizing behavior is, e.g. is it always the same size, or resizable with a minimum, etc.
And then in IB you can build the constraints necessary to create that effect. e.g.:
Alternatively, you could put these controls into a stack view to get a similar result.
Interestingly enough, if I set the ServiceControlViewController's view to e.g. be an NSButton, then it is correctly added and not squashed to zero height. It only happens with the Custom Views I create.
Correct. This is because an NSButton has something your custom NSViews do not have: an intrinsicContentSize. This is what the stack view uses to size and position your added views.
So, override intrinsicContentSize in your custom views and all will be well.

iOS8 Keyboard Extension clipsToBounds

I'm trying to write a custom keyboard for iOS8 and so far, minus the odd hiccup, I've not had too many issues. However, when I create a view and add it as a subview of a UIButton I've added to the keyboard view the newly added view is clipped at the top of the keyboard view. From what I can tell, the hierarchy is as follows:
UIView (popup) -> UIButton (actual "key") -> UIInputView
With this hierarchy, the top-level UIView is being clipped inside the UIInputView. Each UIView has had clipsToBounds set to false, and I also set the UIView (self.view) to false within the UIInputViewController, but that doesn't seem to have helped.
It could be that this is a restriction of the extension system currently, but hopefully it's something silly I'm doing!
This is actually not possible. According to the docs it states "In addition, it is not possible to display key artwork above the top row, as the system keyboard does on iPhone when you tap a key in the top row.", which is a shame.
Thanks to #Spentak for pointing that out

Adding a subview to UITableCellView

I want to add a subview to the UITableCellView class. However, non of the provided views in the class seem to be able to do exactly what I was looking for.
I basically want to add my own background view, filling the whole cell. However, if I replace the backgroundView, the style from the grouped table view layout isn't displayed anymore. If I add a subview to backgroundView, the subview is not shown at all. If I add a subview to the contentView, I can't draw behind the accessory icon.
What am I missing?
Basically you can't change the backgorund of GroupedTable View.
Try using it with PlainTable.
and add the your backgroung image (of size = cellsize) to cellforRowAtIndex method.
You might want to take a look at this article:
"Easy custom UITableView Drawing"
In particular:
First: the UITableView does not itself
draw anything except the background.
To customize the background of a
UITableView, all you need to do is set
its backgroundColor to [UIColor
clearColor] and you can draw your own
background in a view behind the
UITableView.
Simply add the custom view as part of your contentView. Set a unique reuse identifier for that cell, configure it when you create it and from then on simply reset the data components (this is easiest to do if you create a custom cell controller class so that it can track all the parts and use setters/getters for the data).