Build your first custom control by learning how to compose UIKit components to create a powerful icon.
This is a companion discussion topic for the original entry at https://www.raywenderlich.com/4276-introducing-custom-controls/lessons/2
Build your first custom control by learning how to compose UIKit components to create a powerful icon.
Hi,
I’m using your tutorial to crate my own custom view.
but i having problems with autolayout and interface builder.
you can see the full problem in stack overflow
Thanks,
Ilan
Hi Ilan,
There are a couple of reasons that might explain the behaviour you’re seeing. The first is that the constraints inside that custom view don’t define the size. Therefore it’ll depend on external constraints to define the size. What constraints do you have set up in IB? If they don’t determine the size of that view, then AL won’t know how to size it.
You can provide the intrinsic content size to avoid this - which would allow you to choose a “favourite” size, but then also override it from outside the custom view.
The other reason you could be seeing this is the result of a confusing issue with interface builder. When a view is instantiated in code, you need to set translatesAutoresizingMaskIntoConstraints
to false
as you have done. However, for some reason, the live rendering in IB expects this to be true
.
This is very confusing, but it’s likely that this is causing the issues you’re seeing - the difference between running the code and IB.
To get around this, try removing the translatesAutoresizingMaskIntoConstraints = false
line from setupView()
and update init(frame:)
to match the following:
override init(frame: CGRect) {
super.init(frame: frame)
#if !TARGET_INTERFACE_BUILDER
translatesAutoresizingMaskIntoConstraints = false
#endif
setupView()
}
Check that your constraints are set up correctly in IB and then give the code snippet above a try to see whether that fixes the issue.
sam
Thanks for the response.
I removed
translatesAutoresizingMaskIntoConstraints = false
from setup view, and everything is working great.
But the macro TARGET_INTERFACE_BUILDER doesn’t exist for me.
(I’m using Swift 2.2)
Ilan
Great! And thanks for the pointer on the deprecation of TARGET_INTERFACE_BUILDER
. Will investigate what it’s been replaced with.
sam
Hi Sam,
I have watched some of your videos tutorials, you are a great tutor!!!
In this video, you calling setContentHuggingPriority for the IconControl it-self (7:30), in addition to the label and imageView.
I do not understand the purpose of it. You have not overridden the method intrinsicContentSize() for IconControl, as far as I know, calling setContentHuggingPriority, in this situation, should have no effect.
Is that correct?
Hey,
From what I remember, I believe you’re correct - it’ll have no effect. Content hugging is not used internally for a UIView, but is used to determine how the control will interact with its siblings.
This is especially important when views appear inside stack views. If you haven’t already, I urge you to check out the stack views series:
https://www.raywenderlich.com/video-tutorials#stackviews
sam
Any chance you could cover building custom controls with xib files? I’d love to build visually the multiple elements of my app, separately and independently, to only then start piecing them together in my views. I can’t find a good tutorial on that online or anywhere, I managed to hack together something that works, but I’m certain it’s not the correct way to do it.
true, this should be build in interface builder
Hi Sam,
I was wondering is there a way to make only one side of the view have a corner radius? As I wanted to build a view that acts like a button sitting on the edge of the screen and when pressed a list of controls slide out.
Thanks
/ Musa
This is possibly something that could have been covered in this series, but there’s a limit to what can be fitted in 10 videos. The problem with XIB-based or storyboard-based custom controls is that they are a bit hacky to get working correctly.
I believe that this series is due to be updated in the next cycle, so I’ll suggest it as an addition to the existing content.
cheers!
sam
Hi @musa,
The cornerRadius
property on CALayer
affects all corners equally - there is no way to select which corner you want.
There are several options to achieve the effect that you’re after:
CAShapeLayer
that has the appropriate shape and use that the background to your view.Give one of these a try and see how it goes.
sam
Hi really cool videos I’m on swift 3 and i don’t understand why you add sharedInitialization() into an extension because when i do that, i’ve got an error : “use of unresolved identifier sharedInitialization”, so i have change my code to add this function into my class and no problem. So why use an extension ? Thanks you
I like to use extensions to separate functionality, but it’s entirely a personal preference. The difference in Swift 3 are the access specifiers. In Swift 3 private
restricts access to the local scope only - and the new fileprivate
specifier is equivalent to private
in Swift 2; i.e. access is restricted to just that file.
Switch private
for fileprivate
and you should be fine.
sam
Thanks is now run perfectly. I have test coding with extension, really good
Glad you were able to get it going!