gpt4 book ai didi

Swift:在 View 中水平和垂直居中 NSAttributedString

转载 作者:行者123 更新时间:2023-11-28 07:32:00 27 4
gpt4 key购买 nike

你好,

我有一个 CardButton 类:UIButton。在此 CardButton 的绘制方法中,我想在其中添加并居中(垂直和水平)NSAttributed String,它基本上只是一个表情符号。结果看起来像这样:

enter image description here

但是,NSAttributedString 只能在容器内的水平维度上居中对齐。

我的解决方案:

  1. 在 CardButton 中创建一个 containerView
  2. 在它的容器(即 CardButton)中垂直和水平居中 containerView
  3. 在 containerView 中添加 NSAttributedString 并调整 containerView 的大小以适应字符串的字体。

所以结果看起来像这样:

enter image description here

我的尝试是这样的:

class CardButton: UIButton {

override func draw(){
//succesfully drawing the CardButton

let stringToDraw = attributedString(symbol, fontSize: symbolFontSize) //custom method to create attributed string

let containerView = UIView()
containerView.backgroundColor = //green
addSubview(containerView)

containerView.translatesAutoresizingMaskIntoConstraints = false
let centerXConstraint = containerView.centerXAnchor.constraint(equalTo: (self.centerXAnchor)).isActive = true
let centerYConstraint = containerView.centerYAnchor.constraint(equalTo: (self.centerYAnchor)).isActive = true

stringToDraw.draw(in: containerView.bounds)
containerView.sizeToFit()

}
}

长话短说,我非常失败。我首先尝试将 containerView 添加到 cardButton,将背景设为绿色,并为其设置固定的宽度和高度,以确保它被正确添加为 subview 。它做了。但是一旦我尝试对它进行主动约束,它就会完全消失。

知道如何解决这个问题吗?

最佳答案

总是有不止一种方法可以实现任何特定的 UI 设计目标,但下面的过程相对简单,并且已根据您的问题中提出和理解的要求进行了调整。

UIButton.setImage 方法允许将图像分配给 UIButton,而无需显式创建容器。

UIGraphicsImageRenderer 方法允许从各种组件(包括 NSAttributedText 和大量自定义形状)制作图像。

利用这两个工具为您的项目提供基础的过程将是:

  1. 渲染具有适当组件和大小的图像
  2. 将呈现的图像分配给按钮

可以为这个功能创建一个类,但这里没有探讨。

此外,您的问题提到在应用约束时内容会消失。当图像尺寸对于容器而言太大、约束将内容定位在 View 之外以及可能存在大量其他条件时,可以观察到这种效果。

Rounded rectangles and Emoji with NSAttributedString

下面的代码产生上面的图像:

func drawRectangleWithEmoji() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))

let img = renderer.image { (ctx) in
// Create the outer square:
var rectangle = CGRect(x: 0, y: 0, width: 512, height: 512).insetBy(dx: 7.5, dy: 7.5)
var roundedRect = UIBezierPath(roundedRect: rectangle, cornerRadius: 50).cgPath
// MARK: .cgPath creates a CG representation of the path

ctx.cgContext.setFillColor(UIColor.white.cgColor)
ctx.cgContext.setStrokeColor(UIColor.blue.cgColor)
ctx.cgContext.setLineWidth(15)

ctx.cgContext.addPath(roundedRect)
ctx.cgContext.drawPath(using: .fillStroke)

// Create the inner square:
rectangle = CGRect(x: 0, y: 0, width: 512, height: 512).insetBy(dx: 180, dy: 180)
roundedRect = UIBezierPath(roundedRect: rectangle, cornerRadius: 10).cgPath

ctx.cgContext.setFillColor(UIColor.green.cgColor)
ctx.cgContext.setStrokeColor(UIColor.green.cgColor)
ctx.cgContext.setLineWidth(15)

ctx.cgContext.addPath(roundedRect)
ctx.cgContext.drawPath(using: .fillStroke)

// Add emoji:
var fontSize: CGFloat = 144
var attrs: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: fontSize)//,
//.backgroundColor: UIColor.gray //uncomment to see emoji background bounds
]

var string = "❤️"
var attributedString = NSAttributedString(string: string, attributes: attrs)
let strWidth = attributedString.size().width
let strHeight = attributedString.size().height
attributedString.draw(at: CGPoint(x: 256 - strWidth / 2, y: 256 - strHeight / 2))

// Add NSAttributedString:
fontSize = 56
attrs = [
.font: UIFont.systemFont(ofSize: fontSize),
.foregroundColor: UIColor.brown
]

string = "NSAttributedString"
attributedString = NSAttributedString(string: string, attributes: attrs)
let textWidth = attributedString.size().width
let textHeight = attributedString.size().height
attributedString.draw(at: CGPoint(x: 256 - textWidth / 2, y: 384 - textHeight / 2))

}

return img
}

激活 NSLayoutContraints 然后可以为按钮设置新图像:

    override func viewDidLoad() {
super.viewDidLoad()
view = UIView()
view.backgroundColor = .white

let buttonsView = UIView()
buttonsView.translatesAutoresizingMaskIntoConstraints = false
// buttonsView.backgroundColor = UIColor.gray
view.addSubview(buttonsView)

NSLayoutConstraint.activate([
buttonsView.widthAnchor.constraint(equalToConstant: CGFloat(buttonWidth)),
buttonsView.heightAnchor.constraint(equalToConstant: CGFloat(buttonWidth)),
buttonsView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
buttonsView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])

let cardButton = UIButton(type: .custom)
cardButton.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
cardButton.setImage(drawRectangleWithEmoji(), for: .normal)

let frame = CGRect(x: 0, y: 0, width: buttonWidth, height: buttonWidth)
cardButton.frame = frame

buttonsView.addSubview(cardButton)

}

我们将不胜感激您的评论以及对所提供代码的建设性审查。

关于Swift:在 View 中水平和垂直居中 NSAttributedString,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54438356/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com