You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:如何让旋转后的UILabel在背景UIImageView中居中?

解决UILabel无法在背景UIImageView中居中的问题

问题描述

我编写了以下iOS Swift代码,运行后发现UILabel并未在背景UIImageView中居中,请问该如何调整代码解决这个问题?

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Create the background image view
        let backgroundImage = UIImageView(image: UIImage(named: "cardStock1"))
        backgroundImage.translatesAutoresizingMaskIntoConstraints = false
        backgroundImage.layer.borderWidth = 2
        backgroundImage.layer.borderColor = UIColor.darkGray.cgColor
        backgroundImage.layer.shadowColor = UIColor.darkGray.cgColor
        backgroundImage.layer.shadowOffset = CGSize(width: 4, height: 4)
        view.addSubview(backgroundImage)
    
        NSLayoutConstraint.activate([
            backgroundImage.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            backgroundImage.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            backgroundImage.topAnchor.constraint(equalTo: view.topAnchor),
            backgroundImage.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    
        let label1 = UILabel()
        label1.translatesAutoresizingMaskIntoConstraints = false
        label1.text = "Hello World"
        label1.font = UIFont.init(name: "HelveticaNeue-Light", size: 55)
        label1.textColor = .gray
        label1.rotate(degrees: -7)
        view.addSubview(label1)
    
        NSLayoutConstraint.activate([
            label1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            label1.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            label1.widthAnchor.constraint(equalToConstant: 300),
            label1.heightAnchor.constraint(equalToConstant: 160)
        ])
    }
}

extension UIView {
    func rotate(degrees: CGFloat) {
        rotate(radians: CGFloat.pi * degrees / 180.0)
    }

    func rotate(radians: CGFloat) {
        self.transform = CGAffineTransform(rotationAngle: radians)
        self.layoutIfNeeded() // Update layout after rotation
    }
}

问题原因

你的代码存在三个核心问题:

  • UILabel直接添加到主view而非背景UIImageView,旋转后的视觉位置会与背景图中心产生偏移;
  • 提前调用了旋转方法,且旋转方法中多余的layoutIfNeeded会干扰约束的正常生效;
  • 给Label设置了固定宽高约束,旋转后内容的视觉中心会偏离布局约束的中心。

修改后的代码

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // 创建背景图片视图
        let backgroundImage = UIImageView(image: UIImage(named: "cardStock1"))
        backgroundImage.translatesAutoresizingMaskIntoConstraints = false
        backgroundImage.layer.borderWidth = 2
        backgroundImage.layer.borderColor = UIColor.darkGray.cgColor
        backgroundImage.layer.shadowColor = UIColor.darkGray.cgColor
        backgroundImage.layer.shadowOffset = CGSize(width: 4, height: 4)
        view.addSubview(backgroundImage)
    
        NSLayoutConstraint.activate([
            backgroundImage.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            backgroundImage.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            backgroundImage.topAnchor.constraint(equalTo: view.topAnchor),
            backgroundImage.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    
        let label1 = UILabel()
        label1.translatesAutoresizingMaskIntoConstraints = false
        label1.text = "Hello World"
        label1.font = UIFont(name: "HelveticaNeue-Light", size: 55)
        label1.textColor = .gray
        // 将Label添加到背景图视图上
        backgroundImage.addSubview(label1)
    
        NSLayoutConstraint.activate([
            // 相对于背景图居中
            label1.centerXAnchor.constraint(equalTo: backgroundImage.centerXAnchor),
            label1.centerYAnchor.constraint(equalTo: backgroundImage.centerYAnchor),
            // 移除固定宽高,让Label自适应内容
            label1.widthAnchor.constraint(greaterThanOrEqualToConstant: 0),
            label1.heightAnchor.constraint(greaterThanOrEqualToConstant: 0)
        ])
        
        // 约束生效后再执行旋转
        label1.rotate(degrees: -7)
    }
}

extension UIView {
    func rotate(degrees: CGFloat) {
        rotate(radians: CGFloat.pi * degrees / 180.0)
    }

    func rotate(radians: CGFloat) {
        self.transform = CGAffineTransform(rotationAngle: radians)
        // 移除多余的layoutIfNeeded,避免干扰约束布局
    }
}

修改说明

  • 将UILabel的父视图改为背景UIImageView,约束直接关联背景图的中心,确保视觉上完全在背景图内居中;
  • 调整旋转方法的调用时机,在约束激活完成后再执行旋转,保证布局先稳定再应用变换;
  • 移除旋转方法中的layoutIfNeeded,避免提前触发布局打乱约束逻辑;
  • 替换固定宽高约束为自适应约束(或直接移除固定宽高),让Label根据内容自动调整尺寸,防止旋转后内容偏移。

修改后效果

Label在背景图中居中的效果

内容的提问来源于stack exchange,提问作者ICL1901

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:27:02