1

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];
PaulB
  • 128
  • 8

1 Answers1

1

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.

PaulB
  • 128
  • 8
  • I don't understand this solution to the problem, but your answer gave me hope of finding my own solution which I did. If you could add some relevant code to your answer that would be cool! It definitely turned out to be a "timing" issue for me... I just switched the problematic code into a `viewDidAppear` func which loaded later and correctly for different screen sizes. – PlateReverb Jan 19 '17 at 16:16
  • I'm glad that I helped someone. My memory of this is vague; but, as I recall, I put the slider into a containing view that was the size and shape of the final slider. I did this so I could use auto layout. I then programaticly placed the slider into the container view and then transformed it to match the container view's dimensions. My mistake was adding the slider to the container view and rotating it in the wrong place - before the container view was laid out. I will try to edit my answer to be more clear. – PaulB Jan 20 '17 at 21:06
  • How do you know the order between the container view being laid out and your code to rotate the slider? The order of autolayout/IB stuff and `viewDidLoad` functions is a total mystery to me still (prior to my problem, I had assumed IB/autolayout would always happen first. Here's a link to my specific problem (and "hacky" solution) if you are interested: http://stackoverflow.com/questions/41734256/uislider-handle-changes-width-on-different-size-ipads – PlateReverb Jan 20 '17 at 21:34
  • btw, putting the code in `viewDidAppear` also solved the problem for me, but I preferred to put the code in a button which makes the view in question visible, since I could be sure that way it would only happen once (via an "if verticalTransformIsTrue == false" apply transform) – PlateReverb Jan 20 '17 at 21:36
  • I wish I knew the order of all the method calls. I have never found any good documentation. And Unfortunately, I don't remember where I read that my code was in the wrong place. – PaulB Jan 21 '17 at 23:35