Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@IBDesignable - view not rendering as expected

Tags:

I have a custom UIView subclass that I am trying to render using @IBDesignable.

I have an@IBInspectable property named image, which I set from the interface builder.

When I open the interface builder the image that I choose is not rendered properly in the view, that is, it looks like some trouble with autolayout. When I checked the Report navigator I am getting a warning in the Interface Builder group.

Showing All Messages
(null): -pie being ignored. It is only used when linking a main executable

This happens under the Link <IBDESIGNABLE_EXECUTABLE> section.

I have no idea how to fix this. Tried many solutions from SO. Cleaning build folder, clearing derived data etc. Nothing worked.

Please provide your valuable comments or a solution to this problem. Thanks! :)

EDIT:

Thanks to @Rob I could zero in to the problem.

What I have:

An IBDesignable UIView Subclass with properties:

  • an@IBInspectable property named image.
  • an ImageView
  • a ScrollView

I initialise and add the ScrollView and ImageViews as subviews using

required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    initialiseImageView()
}

override init(frame: CGRect) {
    super.init(frame: frame)
    initialiseImageView()
}

Problem:

In initialiseImageView():
I add the scrollView as subview of the UIView and ImageView as the subview of the scrollView to use the viewForZooming delegate. I also add constraints to keep the views in place.
The problem is when I use:

self.translatesAutoresizingMaskIntoConstraints = false

If I use this I get autolayout warnings at runtime. But the imageView is misplaced in interface builder, although the image is rendered correctly.

If I comment the same, everything is as expected in interface builder. But the UI breaks at runtime due to AutoresizingMaskIntoConstraints.


I have the code in github. I am trying the latter approach mentioned in TN2154

I am setting all AutoresizingMaskIntoConstraints to be false and adding the constraints for the subviews in the code itself. The constraints for the UIView subclass are added in the interface builder directly and no warnings exist as of now. The code works as expected at runtime also. The IBDesignable part is the one that is not working as expected.


Strangely enough, When I removed the line

self.translatesAutoresizingMaskIntoConstraints = false

everything is working perfectly. The error that I used to get at runtime is now gone. I don't know if something else that I did fixed it. Thanks a lot for helping to pin point the issue @Rob.

like image 524
GoGreen Avatar asked Oct 21 '16 06:10

GoGreen


1 Answers

BTW, I just did a quick @IBDesignable with an @IBInspectable that was a UIImage and a draw(rect:) that rendered that image and it worked fine:

@IBDesignable class CustomView: UIView {

    @IBInspectable var image: UIImage?

    override func draw(_ rect: CGRect) {
        image?.draw(at: CGPoint.zero)
    }

}

When I do that in a separate target (as one should with designables), I also see the same warning:

ld: warning: -pie being ignored. It is only used when linking a main executable

I suspect that warning may be a red herring. The man pages for ld described -pie option as follows:

This makes a special kind of main executable that is position independent (PIE).

You can toggle this setting if you go to the link settings for your designables' target and change the "Generate Position-Dependent Executable" in the "Linking" settings. Then that warning will go away. Personally, I've never noticed that warning and never changed this settings, and never noticed any adverse affects, but if you want to confirm this for your own sense of satisfaction, try changing this setting and see if you can get the warning to go away.

Bottom line, your @IBDesignable problem probably rests elsewhere, but it's hard to diagnose on the basis of the information provided. We need more information (or, ideally, a MCVE).


It's hard to comment on your autolayout warnings without seeing what those warning are, but I'd guess that (a) you're adding a subview; but (b) not setting the constraints for said subview; and therefore (c) that when you set translatesAutoresizingMaskIntoConstraints = false, that your constraints are ambiguous and therefore result in error messages and unexpected layout at runtime. Or maybe it's a symptom of the idiosyncrasies of scroll views. But it's hard to say without seeing (a) actual autolayout error; (b) what subviews your @IBDesignable added; and (c) what constraints you added for your subviews.

Bottom line, make sure that your programmatically added subviews have all of their constraints unambiguously defined. Also remember that constraints for scrollview subviews act differently that many constraints, defining the contentSize of the scroll view rather than the size of the subviews. (On this latter point, see TN2154.)

like image 165
Rob Avatar answered Sep 25 '22 16:09

Rob