在layoutSubviews中旋转视图

背景和目标

目标:我想旋转并翻转一个UITextView 。 ( 为什么:看我以前的问题 )

问题:如果我直接在UITextView上进行转换,文本布局会因某种未知的原因而变得混乱。

解决scheme:UITextView放在UIView容器中,然后对容器执行转换。

新问题:旋转视图上的自动布局(或任何types的布局)成为主要的头痛问题 。

build议的解决scheme:使UIView的子类充当旋转和翻转的UIView的附加容器。 然后自动布局应该在这个自定义视图上工作。

在这里输入图像说明

目前的问题

它在第一次出现的时候都有效( UITextView有黄色背景):

在这里输入图像说明

但是当方向改变时,会发生以下情况(蓝色是IB中设置的子类UIView背景):

在这里输入图像说明

如果禁用了rotationView.addSubview(textView)行,那么旋转容器视图(红色)就可以重新定位,即使在方向更改时也是如此:

在这里输入图像说明

所以这个问题一定是关于我添加UITextView 。 但我该怎么做呢?

 class MongolTextView: UIView { // properties var rotationView: UIView! var textView: UITextView! // This method gets called if you create the view in the Interface Builder required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } // This method gets called if you create the view in code override init(frame: CGRect){ super.init(frame: frame) self.setup() } override func awakeFromNib() { super.awakeFromNib() self.setup() } func setup() { rotationView = UIView(frame: self.frame) rotationView.backgroundColor = UIColor.redColor() self.addSubview(rotationView) textView = UITextView(frame: CGRectZero) textView.backgroundColor = UIColor.yellowColor() textView.text = "This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text This is some text " } override func layoutSubviews() { super.layoutSubviews() // set the size of the rotation container view let width = self.bounds.width let height = self.bounds.height rotationView.frame = CGRect(origin: CGPoint(x: CGFloat(0), y: CGFloat(0)), size: CGSize(width: height, height: width)) textView.frame = rotationView.bounds // Problem lines here??? rotationView.addSubview(textView) // Problem lines here??? // rotate, translate, and flip the container view var rotation = CGAffineTransformMakeRotation(CGFloat(-M_PI_2)) // the following translation repositions the top left corner at the origin of the superview var translation = CGAffineTransformMakeTranslation((rotationView.bounds.height / 2)-(rotationView.bounds.width / 2), (rotationView.bounds.width / 2)-(rotationView.bounds.height / 2)) var rotationAndTranslation = CGAffineTransformConcat(rotation, translation) var transformPlusScale = CGAffineTransformScale(rotationAndTranslation, CGFloat(-1), CGFloat(1)) rotationView.transform = transformPlusScale } } 

如果我不能得到这个工作…

虽然我现在在这里遇到了drawRect() ,但我的下一个计划是重写drawRect()来进行转换。 不过,这并不是我的第一select,因为这样做会减慢性能。

问题中的代码问题似乎是转换不断增加彼此。 为了解决这个问题,解决scheme是每次重置转换,即将其设置为标识转换。

 rotationView.transform = CGAffineTransformIdentity 

这是显示关键部分的部分实现。

 import UIKit @IBDesignable class UIVerticalTextView: UIView { var textView = UITextView() let rotationView = UIView() var underlyingTextView: UITextView { get { return textView } set { textView = newValue } } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override init(frame: CGRect){ super.init(frame: frame) self.setup() } override func awakeFromNib() { super.awakeFromNib() self.setup() } func setup() { rotationView.backgroundColor = UIColor.redColor() textView.backgroundColor = UIColor.yellowColor() self.addSubview(rotationView) rotationView.addSubview(textView) // could also do this with auto layout constraints textView.frame = rotationView.bounds } override func layoutSubviews() { super.layoutSubviews() rotationView.transform = CGAffineTransformIdentity // *** key line *** rotationView.frame = CGRect(origin: CGPointZero, size: CGSize(width: self.bounds.height, height: self.bounds.width)) rotationView.transform = translateRotateFlip() } func translateRotateFlip() -> CGAffineTransform { var transform = CGAffineTransformIdentity // translate to new center transform = CGAffineTransformTranslate(transform, (self.bounds.width / 2)-(self.bounds.height / 2), (self.bounds.height / 2)-(self.bounds.width / 2)) // rotate counterclockwise around center transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2)) // flip vertically transform = CGAffineTransformScale(transform, -1, 1) return transform } } 

我最近的实现很可能在这个github链接中find。

在debugging模式下检查你的宽度和高度。 我猜他们在轮换之前和之后都是一样的。 这样你的屏幕截图将会被期待。

第二件事是你应用两次转换。

你有旋转视图 – >你应用转换 – >你在手机上改变框架旋转 – >以前的转换仍然适用 – >然后你应用另一个转换。 也许你的答案在这里。

编辑:

可能的解决scheme:

你可以检测到你的女巫方向

  UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if(orientation == 0) //Default orientation //UI is in Default (Portrait) -- this is really a just a failsafe. else if(orientation == UIInterfaceOrientationPortrait) //Do something if the orientation is in Portrait else if(orientation == UIInterfaceOrientationLandscapeLeft) // Do something if Left else if(orientation == UIInterfaceOrientationLandscapeRight) 

然后决定如何处理这个问题。

如果方向是比你拍摄的肖像

 width = self.bound.size.width; height = self.bound.size.height; 

如果不

 height = self.bound.size.width; width = self.bound.size.height;