gpt4 book ai didi

ios - 在 layoutSubviews() 内部设置子层的框架使得无法更改它。有什么解决方法吗?

转载 作者:行者123 更新时间:2023-11-28 16:16:16 25 4
gpt4 key购买 nike

我正在开发可自定义的 UITextField(请参阅下面的代码)。我在底部添加了一个边框(你可以在 Storyboard中设置它)。但是,我在设置包含此边框的 CALayer 的框架时遇到了问题。

如果我在 var showBottomBorderdidSet 方法中设置它,它就不会出现在屏幕上。我认为这是因为尚未计算(UITextField 的)框架(可能在此之前调用了 didSet)。

所以我把它移到了 layoutSubviews() 方法中(见下面的代码)。这非常有效。

但是现在我有另一个问题。我真的不能再改变那个框架了。每次我更改它时,它都会被 layoutSubviews() 重置,我认为这是当时调用的。

在我的代码底部,有方法 textFieldDidBeginEditing。在那里,我想向上移动我的底部边框(动画)。但它不起作用。边界不会移动到任何地方。正如我所说,我认为这是因为我在 layoutSubviews() 方法中设置了框架。

有没有更好的方式来设置下边框的边框?一种允许我改变东西的方式?

@IBDesignable
class CustomizableTextField: UITextField, UITextFieldDelegate {

// MARK: - Properties
private var bottomBorder = CALayer()

// MARK: - @IBInspectables
@IBInspectable var roundCorners: CGFloat = 0 {
didSet {
self.layer.cornerRadius = roundCorners
self.clipsToBounds = true
}
}

/** -- */
@IBInspectable var borderWidth: CGFloat = 1.0 {
didSet {
self.layer.borderWidth = self.borderWidth
}
}
@IBInspectable var borderColor: UIColor = UIColor.white {
didSet {
self.layer.borderColor = self.borderColor.cgColor
}
}
/** -- */

/** -- */
private var showBottomBorder: Bool = false {
didSet {
switch showBottomBorder {
case true:
bottomBorder.borderColor = self.bottomBorderColor.cgColor
bottomBorder.borderWidth = self.bottomBorderWidth

self.layer.addSublayer(bottomBorder)
self.layer.masksToBounds = true
break
case false:
bottomBorder.removeFromSuperlayer()
break
}
}
}
@IBInspectable var bottomBorderWidth: CGFloat = 1.0 {
didSet {
self.showBottomBorder = false
self.showBottomBorder = true
}
}
@IBInspectable var bottomBorderColor: UIColor = UIColor.white {
didSet {
self.showBottomBorder = false
self.showBottomBorder = true
}
}
/** -- */

/** -- */
// Somwhow, the default panel for my font color doesn't change anything, so I created this
@IBInspectable var fixedFontColor: UIColor = UIColor.white {
didSet {
self.textColor = fixedFontColor
}
}
@IBInspectable var placeholderFontColor: UIColor = UIColor.white {
didSet {
var placeholderTxt = ""
if let txt = self.placeholder {
placeholderTxt = txt
}

self.attributedPlaceholder = NSAttributedString(string: placeholderTxt, attributes: [NSForegroundColorAttributeName: placeholderFontColor])
}
}
/** -- */

// MARK: - Overrides and Initializers
override init(frame: CGRect) {
super.init(frame: frame)
}

override func layoutSubviews() {
super.layoutSubviews()
// HERE
bottomBorder.frame = CGRect(x: 0, y: self.frame.size.height - self.bottomBorderWidth, width: self.frame.size.width, height: self.frame.size.height)
}

// setting the textField delegate to self
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)

//self.borderStyle = .none
self.delegate = self
}

// MARK: - Events
func textFieldDidBeginEditing(_ textField: UITextField) {

}

最佳答案

您可以在 UITextFiled 上使用 扩展 来设置边框。

并使用 KVC 保留对它的引用。

通过覆盖 LayoutSubview,每个布局都会改变,我们检查边框是否存在,如果存在则将其删除,并使用新框架重新创建一个新的:

import UIKit

let MyTopBorder = "myTopBorder"
let MyBottomBorder = "myBottomBorder"
struct Defaults {
static let width = CGFloat(1.0)
static func bottonBorderFrame(view: UIView)->CGRect {
return CGRect(x: CGFloat(0), y: view.frame.size.height - Defaults.width, width: view.frame.size.width, height: view.frame.size.height)
}
static func topBorderFrame(view: UIView)->CGRect {
return CGRect(x: CGFloat(0), y: CGFloat(0) , width: view.frame.size.width, height: Defaults.width)
}
}

extension UITextField
{
func setBottomBorder(color:CGColor)
{
if let isBottomBorder = self.getBottomBorderIfExists() {
isBottomBorder.removeFromSuperlayer()
}
self.setBorderWithFrame(Defaults.bottonBorderFrame(self), color: color, andKey: MyBottomBorder)
}

func setTopBorder(color:CGColor)
{
if let isTopBorder = self.getTopBorderIfExists() {
isTopBorder.removeFromSuperlayer()
}
self.setBorderWithFrame(Defaults.topBorderFrame(self), color: color, andKey: MyTopBorder)
}

func setBorderWithFrame(frame: CGRect, color: CGColor, andKey: String) {
self.borderStyle = UITextBorderStyle.None;
let border = CALayer()
border.borderColor = color
border.frame = frame
border.borderWidth = Defaults.width
self.layer.addSublayer(border)
self.layer.masksToBounds = true
self.layer.setValue(border, forKey: andKey)
}

func removeTopBorder() {
if let isTopBorder = self.getTopBorderIfExists() {
self.layer.setValue(nil, forKey: MyTopBorder)
isTopBorder.removeFromSuperlayer()
}
}

func removeBottomBorder() {
if let isBottomBorder = self.getBottomBorderIfExists() {
self.layer.setValue(nil, forKey: MyBottomBorder)
isBottomBorder.removeFromSuperlayer()
}
}

private func getBorderIfExistsByKey(key: String)->CALayer? {
if let isBorderSet = self.layer.valueForKey(key) {
if let borderIsCALayer = isBorderSet as? CALayer {
return borderIsCALayer
}
}
return nil
}

private func getTopBorderIfExists()->CALayer? {
return self.getBorderIfExistsByKey(MyTopBorder)
}

private func getBottomBorderIfExists()->CALayer? {
return self.getBorderIfExistsByKey(MyBottomBorder)
}

public override func layoutSubviews() {
super.layoutSubviews()

// Update bottom on frame change
if let isBottomBorder = self.getBottomBorderIfExists() {
let borderColor = isBottomBorder .borderColor
self.removeBottomBorder()
self.setBottomBorder(borderColor!)
}
// Update top on frame change
if let isTopBorder = self.getTopBorderIfExists() {
let borderColor = isTopBorder.borderColor
self.removeTopBorder()
self.setTopBorder(borderColor!)
}
}
}

用法:

  let textField = UITextField(frame: CGRect(x: 100,y: 100, width: 100, height: 100))
textField.backgroundColor = UIColor.blueColor() // Thie color is for visulizing better
self.view.addSubview(textField)
textField.setBottomBorder(UIColor.blackColor().CGColor) // Now you have a border
textField.frame = CGRect(x: 150, y: 200, width: 200, height: 200) // And the border updated to the new frame
// Now if you would like to change from bottom to top, simply do this:
textField.removeBottomBorder()
textField.setTopBorder(UIColor.blackColor().CGColor)

关于ios - 在 layoutSubviews() 内部设置子层的框架使得无法更改它。有什么解决方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39038707/

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