Rotate UIView with offset - uiview

I am writing a MonoTouch iOS application.
I have a group of 4 UIButtons on my main View. They are more or less in a horizontal row. I want to rotate them by an angle (between -90 and +90 degrees) as a group with the right most button being the "anchor" for the group of buttons.
I can't figure out how to do this.
One thing I tried was I put these buttons inside of a UIView and then set the Transform to a CGAffineTransform.MakeRotation, but it rotates around the center of the UIView. I also tried making this parent UIView be wider than it needed to be so that the right most button in the group was in the center of the UIView. This worked for the rotation, but then the large blank section that was the right half of the parent UIView covers up other buttons that are on my main View that I need to be visible.
So my question is how do rotate UIButtons of a UIView where the rotation is around a point that is NOT the center of the UIButton or UIView?

You can change the AnchorPoint of the view's layer, along with the Position to compensate for the shift due to setting the AnchorPoint. For example, say you had a view named ButtonGroup containing the buttons. The following code would rotate them 90 degrees about the lower left corner of the view:
ButtonGroup.Layer.Position = new PointF(ButtonGroup.Frame.Left, ButtonGroup.Frame.Bottom);
ButtonGroup.Layer.AnchorPoint = new PointF (0,1);
ButtonGroup.Layer.AffineTransform = CGAffineTransform.MakeRotation((float)Math.PI/-2);

Related

Off center center.x when working with stackview

I've got a stack view and I'm wanting when the user clicks on one of the buttons a little "bar" view centers underneath it (the view is outside of the stack view). I had this working before I layed out the buttons with autolayout by just setting
movableView.center.x = newView.center.x
and animating it. Now with the buttons in the stack view the movableView's center X does not line up with the buttons' center x's. It's like 1/3 way off centered.
The movable view itself has no autolayout on it.
What is the cause of this and how can I align the center x of views that have auto layout in play?
Without more information this is my best guess as to what the issue may be.
The center attribute is based on the view's frame, which means that it is using the superview (in this case the UIStackView) coordinate system. If your UIStackView's frame.origin.x is not at 0, which is how it appears in your screenshot, you will need to adjust your movableView.center.x accordingly. This could be as simple as:
movableView.center.x = newView.center.x + stackView.frame.origin.x
Another option would be to convert the center to the main view's coordinate system, like this:
movableView.center.x = newView.convert(newView.center, to: self.view).x

What is the proper way to animate a UIView from outside of a view controller into it's center?

I have several UIButtons that animate from the right (outside the bounds of the view controller) into the center of my view controller each time I press a button. I'm currently accomplishing this by animating the .centerX constraint constant of each UIButton from 250 to 0. It works, but the buttons are visible on the right side devices with larger screens. I could just increase the constant to 300 or something, but isn't there a proper way to accomplish this using Auto-Layout?
you can align button's leading edge with VC.view's trailing edge and then animate it by translating along x axis.

position an element with respect to a particular point of an image in storyboard

What I want to do is position an element (a coloured UIView that I use as a background) to my storyboard so that it starts at the middle of an ImageField and fills everything till the bottom of the screen. I'm using xcode7 and swift.
You can align the bottom of your UIView and UIImageView, and keep the height of your UIView as half of that of UIImageView.
Or if you want the view to go till the bottom, you can do it all in storyboard by adding another view that extends from the bottom of the UIImageView to the bottom of the screen.

Fit a Vertical UISlider into an Existing Container View?

I want to create a vertical UISlider and exactly fit it into an existing container view that is sized and placed from a .xib file using autoLayout. But I simply cannot get it to work and I have Googled my fingers bloody.
The closest I have gotten creates a slider that is too long and extends off the screen.
Am I putting the code in the wrong place?
I am putting my code in "layOutSubviews"
Some Points of interest:
1.Per Apple's docs, the view's "frame" is not valid after the transformation and should not be set.
2.The frame of the slider is set to the future parent's dimensions before the transformation (with x and y swapped).
3.The transformed view appears to maintain its bounds in the pre-transformation coordinate frame. i.e. After the 90 degree transformation, the width and height of the transformed view's bounds appear to be swapped.
This code doesn't work. The slider looks right except that it extends off the bottom of the screen. The slider bounds and even the frame (which Apple says is not valid) seem to match the bounds and frame of the container view. The slider doesn't even stay within its own bounds.
[super layoutSubviews];
CGRect trigLevelSliderFrame=self.trigLevelSliderContainer.bounds;
trigLevelSliderFrame.size.height=self.trigLevelSliderContainer.bounds.size.width;
trigLevelSliderFrame.size.width=self.trigLevelSliderContainer.bounds.size.height;
UISlider *mySlider=[[UISlider alloc] initWithFrame:trigLevelSliderFrame];
self.trigSlider=mySlider;
[mySlider release];
self.trigSlider.transform=CGAffineTransformMakeRotation(-M_PI_2);
CGPoint center=CGPointMake(self.trigLevelSliderContainer.bounds.size.width/2,self.trigLevelSliderContainer.bounds.size.height/2);
self.trigSlider.center=center;
[self.trigLevelSliderContainer addSubview:self.trigSlider];
There is no problem with this code to add and rotate the slider. The problem is that the the code must be put into the "layoutSubviews" method of the slider's parent view; instead I had it in the "layoutSubviews" of the parent view of the parent view of the slider. When my original code executed the slider's parent view had not yet been laid out and did not yet have the correct dimensions.
During "layoutSubviews" of a view, the subviews have not yet been laid out and so their bounds are not yet valid. I needed to wait until later in the layout process to get the bounds of the parent view and transform the slider to fit.
In the end, I put the code to add the slider and transform the slider in the "viewDidAppear" of the top level view controller. This was the same code as in the original question - just in a different place.

Position UILabel relative to UIImage in Universal Storyboard using Autolayout Xcode6

I am implementing a custom map view in which I want to add multiple UILabels over an UIImage. Below is the view hierarchy:
When I preview it on iPhone & iPad, UILabel stays relative to the SuperView but I want to stay it relative to a point(x,y) in UIImage so that whatever be the the device, the label should always be with Groovy room.
I can draw text on UIImage, but it is a very costly operation in my scenario as my View will be loaded once & I need to update the label frequently.
Below is the current UI:
As shown, label doesn't stay in Groovy room & goes out of the way.
You need to pin the UILabel to the leading left and top of the UIImageView you wish it to layout relative to. Set the pin offsets to be the relative x and y you wish.
Updated after comments
If you have one big image that will fill the screen and you want to position multiple labels, I think you are going to have to do the positioning in code. The reason I say this is that for different screen sizes you need to change the point the image is shown at.
Suggestion is|
1) For your map, create a table containing the relative position for the centre of each room. E.g. Centre of Room 1 is 25% across and 10% down. Put then in an array. You now have a way of defining the centre if each room regardless of screen size.
2) In your viewDidLoad method, create your UILabels and put them in an array indexed by room number. Add the labels to your main view. You could do this in storyboard if you have an exact number and assign IBOutlets you can put in an array.
3) Implement layoutSubviews and in there set the centre of each label to be the centre of the room plus an offset so it shows below the room label. Call super version first. Use the centre property of the UILabel frame to make this easy. Doing this in layoutSubviews should work around any issues with constraints the system adds itself.
This should let you handle labels for all screen sizes as you are coding the label positions as relative to the image. When running you are converting this relative position to actual points.

Resources