Interface Builder cannot find intrinsicContentSize defined in a custom view - ios

Interface Builder cannot find intrinsicContentSize of a custom view.
For this given view code,
import Foundation
import UIKit
#IBDesignable
final class CustomView1: UIView {
override var intrinsicContentSize: CGSize {
return CGSize(width: 100, height: 100)
}
}
I put a UIView instance and set its class to CustomView1.
It works at first, but if I close and re-open the storyboard, IB sometimes(not always) shows an error.
IB cannot find width of the view.
And this error disappears if I force Update Frames.
It looks like a bug. Or am I missing something important? What's your opinion? Any workaround?

Xcode 11 has intrinsic size option in Size inspector. as below

Related

I can not get this UIView round

This is the final result of the code below:
This is my code:
view.layer.cornerRadius = 0.5 * view.bounds.size.width
view.layer.masksToBounds = true
view.clipsToBounds = true
view is the red UIView. This code is placed in viewWillLayoutSubviews and viewDidLayoutSubviews (not together, but I both tested them).
Besides this SO is not clear about using masksToBounds OR clipsToBounds. I am not sure what to use and when to use one of them above. I also tested it apart.
The green UIView has also clipsToBounds active and rounded corners, but if I remove them both, I still get the same effect... I hope someone can help. This only occurs when I place a UIView, inside another UIView. If the UIView does not has a parent, it works (I get the UIView rounded).
Edit: GitHub link: https://github.com/Jasperav/tests
The problem lies with when the auto-layout engine actually finishes all the layout calculations.
If you move your code to viewDidAppear you will see properly "rounded" corners.
This is a very common case for using a custom view though. In fact, it's easily used as an "IBDesignable" class, so you can see it rendered in Interface Builder.
Create a new file named "RoundedView.swift" with this code:
import UIKit
#IBDesignable
class RoundView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = 0.5 * self.bounds.size.height
}
}
Then assign that class to the View you want to be round. Xcode will build your new class, and it will show up in Interface Builder like so:

Get the intrinsic height of a custom control

How can I get the height of my custom control?
The idea is I will use it to dynamically set the height of some buttons inside the custom control. I've set the Placeholder height to 44 in the Xcode size inspector.
Working off Apple's Start Developing iOS Apps (Swift) tutorial, I am attempting to access frame.size.height and it gives a value of 1000 while the tutorial seems to suggest it should be 44.
class RatingControl: UIView {
...
override public var intrinsicContentSize: CGSize {
let buttonSize = Int(frame.size.height)
print(buttonSize) // prints 1000
let width = (buttonSize * starCount) + (spacing * (starCount - 1))
return CGSize(width: width, height: buttonSize)
}
...
You should never access frame inside intrinsicContentSize. intrinsicContentSize should return the size that perfectly fits the contents of the view, regardless of its current frame.
In your case, I think you can just use 44 for your buttonSize.
The placeholder intrinsic size is just that, placeholder, so that IB interpreter is has some value to work with and can layout the rest of the scene. But in your intrinsicContentSize getter, you implement the real size, which will be used in runtime by the AutoLayout engine. Since you return 1000 as the intrinsic content height, that's what you will see in runtime.

drawRect not called when subclassing UIView and adding it in the interface builder

I am trying to subclass UIView. Code like so:
import UIKit
class CustomView: UIView {
override func drawRect(rect: CGRect) {
// Drawing code
let circlePath = UIBezierPath(ovalInRect: rect)
UIColor.blueColor().setFill()
circlePath.fill()
}
}
I have dragged a UIView onto a UIViewController and set the class to CustomView however the circle doesn't appear (I have set the constraints correctly). Any ideas what I might be doing wrong here? I'm not trying to preview it. Just want to see it when I run the app. Seems I am getting an error in the console too: Unknown class _TtC9MyProject15CustomView in Interface Builder file.
It is likely that the Target Membership for your CustomView.swift file is not set for your app.
In the Project Navigator on the far left, select your file CustomView.swift. Then in the File Navigator on the far right under Target Membership, make sure the box to the left of your app name is checked.

Xcode 7 beta 5, Swift 2: UITableViewCell's subviews are not added to the contentView at runtime

Following phenomena happens when using Xcode 7 beta 5 and Swift 2:
When using a custom UICollectionViewCell that is created in the storyboard, the cell's subviews are not added to the cell's contentView. Thus the cell remains blank on runtime.
If I however create a custom cell class for the cell and then programmatically add the subviews to the contentView and set their frame the cell's content is displayed:
class Cell : UITableViewCell {
#IBOutlet weak var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
NSLog("subiews.count=%d", contentView.subviews.count) // prints "0"
contentView.subviews.count
contentView.addSubview(label)
label.frame = CGRect(x: 0, y: 0, width: 200, height: 21)
}
}
Again, without manually adding the label (that has been added in the storyboard!) and setting its frame, it would not be visible at runtime! In the storyboard the label is a subview of the content view. At run time it is not.
I cannot observe this behavior in latest Xcode 6 with Swift 1.2.
Can somebody confirm this silly behavior? And maybe provide an easier workaround?
Edit:
Luckily view constraints on the cell's subviews are applied after these views have been added programmatically to contentView. Thus at least manually setting their frames is not necessary.
There is a similar question here UITableView Empty with iOS 9 beta 5 update
And my answer for it https://stackoverflow.com/a/32052154/2674336
I can't say if this is a universal solution, but in the exact same scenario (tablviewcell content empty at runtime after updating to XCode 7 beta 5) this solved it for me:
I had to go through every single item inside the content view (including all constraints) and tick the checkbox "Installed" in the properties inspector. Initially only wR hR was checked.

How to change UIView's position in code?

I created a custom ViewCell class attached with a xib layout file, and I added some labels in xib. But when I want to change the labels' position in code, it doesn't work, can you tell me why?
Here are the the relative codes:
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
var bounds = ContentView.Bounds;
UILabel label_period = RetriveViewByID ("label_period") as UILabel;
label_period.ContentMode = UIViewContentMode.Redraw;
label_period.Text = string.Format ("{0}天之旅", m_travel_data.period); \\Works
label_period.Frame = new RectangleF (20, label_period.Frame.Y, label_period.Frame.Width, label_period.Frame.Height);
}
It is weird, because the Text is actually changed, but Frame not.
There are a few things that you could try here.
First of all try calling
label_period.SetNeedsLayout();
or possibly (but rather unlikely)
label_period.SetNeedsDisplay();
If neither of those work I would check to see that you do not have any unnecessary Layout Constraints declared in your .xib.
Although this was directly part of your question, I recommend instead of using RetrieveViewByID(...) just reference the view by its name.
(If you declared the UIViewController in the .xib you should be able to access the view inside the UIViewController with this.label_period )
Finally, although I do not know the specifics of your situation, I recommend switching over to Storyboards, you will run into issues like these less.

Resources