你好,
我有一个CardButton类:UIButton。在此CardButton的draw方法中,我想在其内部添加NSAttributed String并将其居中(垂直和水平),该字符串基本上只是一个表情符号。结果看起来像这样:
但是,NSAttributedString只能在容器内水平尺寸的中心对齐。
我的解决方案:
所以结果看起来像这样:
我为发生这种情况所做的尝试如下:
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,使背景变为绿色,将其宽度和高度固定,以确保将其正确地添加为子视图。它做了。但是,一旦我尝试对其进行主动约束,它就会完全消失。
有什么想法要解决这个问题吗?
答案 0 :(得分:0)
实现任何特定的UI设计目标总是有不止一种方法,但是以下过程相对简单,并且已进行了调整,以适应问题中提出和理解的要求。
UIButton.setImage方法允许将图像分配给UIButton,而无需显式创建容器。
UIGraphicsImageRenderer方法允许通过各种组件(包括NSAttributedText和大量自定义形状)制作图像。
利用这两个工具为您的项目提供基础的过程将是:
可以为此功能创建一个类,但此处未对此进行探讨。
此外,您的问题提到在应用约束时内容会消失。当图像尺寸对于容器来说太大时,可以看到这种效果,约束条件是将内容物置于看不见的位置,并且可能还有其他条件。
以下代码产生以上图像:
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)
}
您的评论以及对所提供代码的建设性审查将不胜感激。