I have a UIView rectangle that I want to resize the width of programatically. I have that working fine, however when the UIView's width resizes, the left edge stays in place and it is the right edge that moves away/closer. I want the opposite effect of this. I want the right edge to stay fixed and have the UIView resize by moving its left edge. I believe the anchor points are what I should be looking into however i have had no luck
I managed to find UIView.rightAnchor however this doesn't seem to do anything. I'm definitely missing something
Unrelated to bounds, there is a very simple way that you can achieve what you are talking about.
This would simply be through animating two changes to the view's frame simultaneously:
UIView.animate(withDuration: 5, animations: {
self.view1.frame.size.width -= 100
self.view1.frame.origin.x += 100
})
This sample code would create something like this:
Of course you can change the speed of the animation if you want it to be basically instantaneous and such, but this method should work for anything you have in mind.
Related
I have an app with certain number of UIViews. I now need to swap their positions horizontally. For example, there is a UIView called X at the left end and one called Y at the right end. At a button click, I want Y to reside where X resided and X to come to UIView Y's initial position. I figure, I must be able to do this by swapping the NSLayoutConstraints of them both(just a guess). But I can't get this to work. Is this idea possible? What will be the objective-C code for this?
These are the results I got after trying out the first code(almost there, but not completely). I have only applied it to the views KWI and DXB. What I want is a blind swap between KWI and DXB
If the views are of the same size, then it is not much of a problem. Assume your two views X and Y are called xView and yView. You could do something like this:
CGRect xViewFrame = xView.frame;
UIViewAutoresizing xViewResizingConstraints = xView.autoresizingMask;
xView.frame = yView.frame;
xView.autoresizingMask = yView.autoresizingMask;
yView.frame = xViewFrame;
yView.autoresizingMask = xViewResizingConstraints;
If you want this animated, you can put it inside a [UIView animateWithDuration: animations:^{}] block, and it should work. (I haven't tested it out though)
You could also change the CGRect xViewFrame to use CGPoint xViewCenter and swap the centers for same-sized views.
The property autoresizingMask tells the program what to do in the case of a screen resize - whether by a change in orientation, or a result of device screen size or any other reason.
If the views are NOT of the same size, you would have to deal with the proper margins of your views, and ensure that they do not get clipped outside the screen.
Hope this helps.
EDIT
It seems that you are using UILabels either as your view, or a subview of the two views. If this is the case, make sure you also swap the NSTextAlignment of the UILabels. Something like this:
NSTextAlignment xTextAlignment = xView.titleLabel.textAlignment;
xView.titleLabel.textAlignment = yView.titleLabel.textAlignment;
yView.titleLabel.textAlignment = xTextAlignment;
I have a messaging view where the user can select emoticons to add to the message. I have a bar above the keyboard where the user can enter their message. It looks something like this: H:|-[UIButton: emoticon]-[UITextField]-[UIButton: send]|
Now I've tried to slide all these over by setting their left constraint to constraint.constant -= screenWidth, but this didn't seem to work, as I got loads of "Could not satisfy constraints" messages in the log and none of them moved. I also had the problem of not knowing where to put the emoticons (it's a bar of UIButton with one emoji each).
Is there a way to do this in a simple way?
If I understand what you're doing right (you're sparse on the details), your problem is that your constraints are still pinned to the start and end.
You will probably need to remove the last item's right constraint before you can scroll anything.
That said, what I usually do in cases like this is wrap everything that's supposed to scroll in a plain UIView. Then I can keep their internal constraints the same, and only the UIView is pinned to the left and right of its superview. To scroll, I simply add a width constraint with the current width, remove the right constraint, and then subtract from the left constraint's constant to scroll it off screen.
That extra view gives me a guarantee that everything stays the size and location it had at the beginning of the animation, and might even allow me to optimize the animation (e.g. I can rasterize the view before I scroll it out, and UIKit then only has to move one layer).
I would like to be able to set clipsToBounds at NO for an UIView but only with the horizontal component.
My content will be displayed on left / right even if it's too large but top / bottom will not be displayed beyond the container's height.
Should I use maskToBounds layer property and add a specific mask ?
You should start by asking yourself why you think you need this. If you want to display the horizontal content when clipsToBounds is YES, why not make the view big enough horizontally? It can go right off the screen on both sides, no problem. A view that is visible when it is not inside its superview is usually a very bad idea in any case (for example, the user can see it but can't touch it, which is usually undesirable and confusing).
Otherwise, this is going to be a very tricky problem. You will probably need to put another view above your view and another view below it, to cover the content that sticks out above and below your view. Crude but effective.
Use UIView's mask property. See documentation
The mask view's width can be maximal, and the height can be the same as the view itself.
maskToBounds needs to be false in this case.
I've been reading a lot of posts here and I see conflicting information.
I'm trying to draw a line over a UIImageView which already contains a picture.
I'll need to draw the line either horizontally, vertically, or not at all based on user selection, without disturbing the existing picture.
Some responses say to draw into the UIImageView directly, some say to subclass a UIImageView or UIView, and still others say to create a view layer.
What is the Best Practice for this, and can you also point me to a tutorial?
Since you need to pan/zoom the image underneath, I suggest you implement a stack like this:
[UIScrollView] on the bottom
[UIImageView] inside the scroll view for pan/zoom
[UIView] on top of the scrollview - for drawing the line
(see this tutorial for line drawing).
Personally I've used this project for implementing pan/zoom -- it's well implemented and takes a lot of the guess work out of it.
The easiest way to do this, since you only want to draw a horizontal or vertical line, is to add a subview to the UIImageView. If you want a horizontal line, set the subview's height to 1-2 points and set the width to the image view's width. If you want the line to be vertical, set the subview's height to the image view's height and set the width to 1-2 points. Set the subview's background color to whatever color you want the line to be.
A subview always appears on top of its superview.
I want to position a sub UIView (sub_UIView) as a subview of parent UIView (parent_UIView). When the parent_UIView resizing/moving, the sub_UIView would stay the relative position of the parent_UIView. For example, the sub_UIView is at the bottom right corner of the parent_UIView. When the parent_UIView is moving, the sub_UIView would stay at the bottom right corner of the parent_UIView automatically.
I managed to do this manually by updating the frame of the sub_UIView when the parent_UIView's frame moving, but how to do this automatically in iOS? are there any properties for this? (similar to autoresizingmask for resizing subviews)
Updated old response, that only mentioned resizing masks
Autolayout (iOS 6)
In iOS 6, autolayout was added, albeit, kinda ugly to work with XCode in a storyboard/xib. Autolayout is way too big to explain, but the essence of it, is that it's a set of rules between views within the hierarchy. Thus, you can stick the x position of a view to the right border of a parent view. See the Auto Layout Programming Guide
Autoresizing Masks (iOS 2)
Take a look at the options in the Size Inspector:
This is the equivalent of doing
myView.autoresizingMask = UIViewAutoresizingMaskFlexibleTopMargin |
UIViewAutoresizingMaskFlexibleLeftMargin |
UIViewAutoresizingMaskFlexibleWidth |
UIViewAutoresizingMaskFlexibleHeight;
Notice that there's a difference between doing it by code and doing it through IB. The IB autoresizing settings for the borders work as struts, selecting the right one, for example, means, "my right border is now stuck to the superview's right border".
On the other hand, code does the opposite, where you need to specify which borders are not strut-ed, aka. they are flexible. Height and Width works normally.
Layout Subviews (iOS 2, but gotchas for iOS5+)
If everything fails, don't start doing manual positioning all over the place, I've been in that position, and it just leads to unmaintanable, spaghetti code, where three or more methods are messing with the same view properties.
Instead, prefer to do all your custom positioning on UIView -layoutSubviews. This method gets called as needed when a setNeedsLayout has been triggered, for example, when the width a view changes, the subviews get the layout subviews event. Also makes implementing rotating interfaces much easier, since this method gets called for the new width, to determine how the animation will look like.
Keep in mind that layout subviews works after Auto Layout/Auto-resizing masks have been performed.