UITextView文本从上到下从左到右排列及旋转后异常求助
解决UITextView竖排(从上到下、从左到右)的排版问题
我之前做中文竖排文本的时候,也踩过直接用transform旋转的坑——视图转了,但内部文本的排版逻辑还是跟着原来的横排尺寸走,自然会出现内容尺寸不匹配、换行错位的问题。这里给你两个靠谱的解决方案,按需选:
方案一:用原生文本排版属性实现(推荐,无transform副作用)
直接通过NSAttributedString设置竖排样式,让UITextView原生支持垂直排版,这是最稳妥的方式,不会有布局错乱的问题:
// 1. 创建竖排的段落样式 let paragraphStyle = NSMutableParagraphStyle() // 设置为垂直排版,从上到下、从左到右的方向 paragraphStyle.baseWritingDirection = .leftToRight paragraphStyle.lineBreakMode = .byWordWrapping // 关键:设置垂直排版的书写方向 paragraphStyle.writingDirection = [.leftToRight, .vertical] // 2. 创建带样式的富文本 let attributedText = NSAttributedString(string: "你的竖排文本内容", attributes: [ .paragraphStyle: paragraphStyle, .font: UIFont.systemFont(ofSize: 16) ]) // 3. 应用到UITextView textView.attributedText = attributedText // 调整textView的尺寸适配竖排内容 // 可以通过计算富文本的size来设置frame或约束 let textSize = attributedText.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: 300), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).size textView.frame = CGRect(x: 50, y: 50, width: textSize.height, height: textSize.width)
这样设置后,文本会原生按照从上到下、从左到右的竖排逻辑排版,换行和尺寸都完全匹配,不需要依赖视图变换。
方案二:修复transform旋转后的布局问题(如果一定要用旋转)
如果因为某些原因必须用transform来实现,那需要手动修正内部的文本容器尺寸和视图布局,步骤如下:
// 1. 先执行你的旋转和翻转操作 textView.transform = CGAffineTransform(rotationAngle: .pi / 2).scaledBy(x: 1, y: -1) // 2. 修正textContainer的尺寸(旋转后宽高互换) let originalContainerSize = textView.textContainer.size textView.textContainer.size = CGSize(width: originalContainerSize.height, height: originalContainerSize.width) // 3. 修正contentSize和contentOffset textView.contentSize = CGSize(width: textView.contentSize.height, height: textView.contentSize.width) textView.contentOffset = CGPoint(x: textView.contentOffset.y, y: textView.contentOffset.x) // 4. 在layoutSubviews里重新调整(如果用AutoLayout,建议重写UITextView子类) class VerticalTextView: UITextView { override func layoutSubviews() { super.layoutSubviews() // 每次布局后重新修正容器尺寸 let originalSize = textContainer.size textContainer.size = CGSize(width: bounds.height, height: bounds.width) // 同步contentSize let newContentSize = CGSize(width: contentSize.height, height: contentSize.width) contentSize = newContentSize } }
这个方法的核心是:旋转只是改变视图的视觉呈现,而UITextView内部的文本排版还是基于textContainer的尺寸,所以必须把容器的宽高互换,让文本在旋转后的“视觉空间”里正确排版。
内容的提问来源于stack exchange,提问作者Buren
相关产品推荐
相关产品推荐

