Setting a UIImageView programatically causes the UIImageView to move? - uiimageview

Regardless of whether Auto Layout is on, when trying to change the UIImageView inside my Prototype Cell, the ImageView appears to move to a different position as you can see in the design below.
IB Design:
Simulator:
I have added Constraints and set them all to 'Required' and even tried deleting the other content in the Prototype Cell, but this doesn't work either.
What could I be doing wrong?
Edit
When I log my constraints, they seem to just be the width and height of the UIImageView
2012-12-02 15:49:30.313 myApp[7551:c07] Constraints - (
"<NSLayoutConstraint:0x80985c0 V:[UIImageView:0x80982d0(80)]>",
"<NSLayoutConstraint:0x8098600 H:[UIImageView:0x80982d0(160)]>"
)
Edit 2
When deleting the UIImageView altogether, it still produces the same output, i.e. the image in the same position.

Ok, so it turn out UITableViewCell already has a UIImageView named "imageView" and changing my IBOutlet to something less generic solved the problem.
Be sure to check the names don't already exist in the UITableView subclass!

Related

How is a subview of an NSView dynamically positioned?

I am attempting to change the coordinates of an NSButton that is contained within a parent NSView and something is clearly not working, because the button position does not change. Both elements are defined in a nib file and the parent view has animation applied to it using CoreAnimation.
I have tried the following.
button.frame.origin.x = 500
and...
var frame:CGRect = button.frame
frame.origin.x = 500
button.frame = frame
Even with the animations disabled, I can not seem to dynamically position the subview. Is there some feature that prevents children views from being positioned programmatically?
Please note that I am using Swift with XCode 6.3.1.
I'm guessing you're using AutoLayout constraints, given you're using the latest tools.
If so, setting a subview's frame directly won't work the way you're expecting (if it does anything at all, it'll cause strange drawing glitches / flashing when mixed with animation). You have to create outlets for your layout constraints and modify them.
If you're not using AutoLayout, I suggest having a look at your button outlet to make sure it's actually connected (ie, you're not talking to nil). Even if the outlet is connected, make sure it's not nil at runtime - you may be trying to talk to the button before the nib is loaded and the outlet / action connections are restored.

NSCollectionView inside NSTableCellView doesn't resize

I want to show a NSCollectionView inside a NSTableCellView. I have it setup correctly, and it works for the most part, but the collectionView's scrollview doesn't seem to resize properly against the NSTableCellView, even though I have auto-layout constraints setup for this.
Is there anything I can do to setup constraints in a way that the scrollview resizes against the NSTableCellView (which should also let the collectionView also resize itself)?
EDIT:
To elaborate, what I really want to do is have the collectionView expand and resize as the window is resized, and have it take up the same width as the tableViewCell, and depending on the number of items in the collection view, resize the height of the outlineView & hence determine the height of the outlineView's row. It works fine when the collectionView is part of an ordinary view, but I can't get it to resize itself inside a NSTableCellView.
Firstly, remove all of the constraints you've set for your collectionview/scrollview.
Now, you will need to make 4 constraints, one for each of the leading, trailing, top and bottom space from the scrollview to its superview. Make sure width and height are not constrained. I've done this in a recent app I've made and it worked rather well.
EDIT: Below in the comments we figured out the column wasn't resizing so the constraints were correctly set.

Can I disable autolayout for a specific subview at runtime?

I have a view that needs to have its frame manipulated programmatically - it's a kind of document view that wraps to its content which is then scrolled and zoomed around a superview by manipulating the frame origin. Autolayout fights with this at runtime.
Disabling autolayout completely seems a bit harsh because it could reasonably be used to handle layout for the other views. It seems like what I might want is some kind of "null constraint".
I had the same problem. But I have resolved it.
Yes, you can disable auto layout at runtime for a specific UIView, instead of disabling it for the whole xib or storyboard which is set by default in Xcode 4.3 and later.
Set translatesAutoresizingMaskIntoConstraints to YES, before you set the frame of your subview:
self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);
I had a similar issue where Autolayout was overriding some of my frame-setting at run time (I had a dynamic view that in some cases pushed a new view controller...pushing and then pressing Back would reset the initial view).
I got around this by putting my manipulation code in viewDidLayoutSubviews of my View Controller. This seems to get called after whatever constraint mojo gets called, but before viewDidAppear, so the user is none the wiser.
Perhaps just setting translatesAutoresizingMaskIntoConstraints to YES (and not adding additional constraints affecting that view) will let you set the frame without fighting the auto layout system.
In iOS 8 you can set an NSLayoutConstraint to be active or not. So if I'm using interface builder, I add all my constraints to an OutletCollection and then activate or deactivate using:
NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)
The particular application I'm using it for here is having different constraints in portrait and landscape mode and I activate/deactivate based on the rotation of the device. It means I can create some complex layout changes all in interface builder for both orientations, and still use auto layout without the verbose auto layout code.
Or you can activate / deactivate using removeConstraints and addConstraints.
I don't know if this will help anyone else, but I wrote a category to make this convenient because I find myself doing this a lot.
UIView+DisableAutolayoutTemporarily.h
#import <UIKit/UIKit.h>
#interface UIView (DisableAutolayoutTemporarily)
// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;
#end
UIView+DisableAutolayoutTemporarily.m
#import "UIView+DisableAutoResizeTemporarily.h"
#implementation UIView (DisableAutoResizeTemporarily)
- (void)resizeWithBlock:(void (^)(UIView * view))block
{
UIView *superview = self.superview;
[self removeFromSuperview];
[self setTranslatesAutoresizingMaskIntoConstraints:YES];
__weak UIView *weakSelf = self;
block(weakSelf);
[superview addSubview:self];
}
#end
I use it like this:
[cell.argumentLabel resizeWithBlock:^(UIView *view) {
[view setFrame:frame];
}];
Hope it helps.
You can set the translatesAutoresizingMaskIntoConstraints type Boolean, Value Yes in the User Defined Runtime Attributes of the UIView you want in the xib/storyboard.
In my view I had a Label and a Text. The label had pan gesture. The label moves around fine during drag. But when I use the text box keyboard, the label resets its position to the original location defined in auto layout. The issue got resolved when I added the following in swift for the label. I added this in viewWillAppear but it can be added pretty much anywhere you have access to the target field.
self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true
Open project in 4.5
Select storyboard
Open the file inspector
Under Interface Builder Document uncheck 'Use Autolayout'
You can split across multiple storyboards if you want to use autolayout for some views.
For me it worked to create the subview programmatically, in my case the auto layout was messing with a view that I needed to rotate around its center but once I created this view programmatically it worked.
I've encountered a similar scenario, where I joined a project that was initiated with auto-layout, but I needed to make dynamic adjustments to several views. Here is what has worked for me:
Do NOT have views or components laid out in interface builder.
Add your views purely programmatically starting with alloc/init and setting their frames appropriately.
Done.
This happened to me in a project without storyboards or xib files. All 100% code. I had an ad banner at the bottom and wanted the view bounds to stop at the ad banner. The view would resize itself automatically after loading. I tried every resolution on this page but none of them worked.
I ended up just creating a sub view with the shortened height and placed that in into the main view of the controller. Then all my content went inside the sub view. That solved the problem very easily without doing anything that felt like it was going against the grain.
I am thinking if you want a view that is not the normal size that fills the window then you should use a sub view for that.
Instead of disabling autolayout, I would just calculate the new constraint with the frame you are replacing. That appears to me to be the appropriate way. If you are adjusting components that rely on constraints, adjust them accordingly.
For example, if you have a vertical constraint of 0 between two views (myView and otherView), and you have a pan gesture or something that adjusts the height of myView then you can recalculate the constraint with the adjusted values.
self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];
For those of you who are using auto layout, please check out my solution here. You should be making #IBOutlet's of the constraints you want to adjust and then change their constants.
if it's xib file:
select the .xib file
select the "File's Owner"
show the Utilities
click on: "File Inspector"
Under "Interface Builder Document" disable: "Use Autolayout"

UITableView Stretching Issue

I have a UIViewController that has an image and label at the top followed by a UITableView. In the IB it looks perfect, but when I run the application in the simulator the UITableView is stretching and taking up the entire screen.
I've turned off all autosizing and set all of the values for stretching to 0, but it's still taking up the entire screen. I even tried some advice I saw on another post which suggested putting the UITableView in a UIView that was sized, but that did not work either.
Any suggestions on how to stop the UITableView from resizing and filling the screen? I am running XCode 4.2.1 with iOS5.
You can give frame size to your tableView like this-
1) make your tableView's IBOutlet property in .h class, and synthesize in .m class.
2) connect it in Xib.
3) than in your .m class place this code in viewDidLoad-
tblView.frame = CGRectMake(0.0f, 30.0f, 320.0f, 50.0f); // you can give any size to your table

iOS. How Do Enable a Transparent Image to Pass Touches to a UIButton Below it?

For an iPad app I am writing I have a container UIView with two subview that are UIView subclasses:
A UIImageView whose image has a portion of it cut away to reveal what is below it.
A UIButton below the UIImageView that is revealed through the cut away portion of the UIImageView.
Since the UIImageView overlaps the UIButton spatially it is preventing touches from reaching the UIButton even though the UIButon is fully visible due to the alpha matte cutout in the UIImageView. How do I allow the UIImageView to pass touches to it's sibling UIButton?
Thanks,
Doug
UIImageView usually won't block touches, UIViews do.
You can set the userInteractionEnabled property on the overlapping views to NO, then touches should go through them.
An other approach would be writing a custom hitTest that redirects the thouches to the button.
In addition to Bastian's answer it was also necessary for me to uncheck the Opaque drawing attribute in interface builder for my UIImageView
Even with user interaction enabled, which is the default value when placing a UIImageView in Interface Builder, the touches should pass through to your button underneath, even if your image view has a solid background. Something else must be going on like a UIView sitting on top of the button.
If you are trying to do something more complex to get touches to pass through to underlying views or a separate view controller whose view is underneath, I created this simple open source library:
https://github.com/natrosoft/NATouchThroughView
The REAMDE and demo show how to use it.

Resources