将底线边框添加到TextView - iOS

时间:2016-07-12 10:28:03

标签: ios swift uitextview

TextView添加底线边框的最佳方法是什么? 我试过这个,但似乎它没有用。它受textview的滚动功能的影响,并且正在TextView

的中间绘制线条
func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.CGColor
        border.frame = CGRectMake(0, self.frame.size.height - width, self.frame.size.width, width)
        self.layer.addSublayer(border)
        self.layer.masksToBounds = true
 }

编辑: TextView具有动态高度。

7 个答案:

答案 0 :(得分:4)

Swift 4版本

func addBottomBorderWithColor() {
    let border = CALayer()
    border.backgroundColor = UIColor.black.cgColor
    border.frame = CGRect(x: 0, y: yourTextArea.frame.height - 1, width: yourTextArea.frame.width, height: 1)
    yourTextArea.layer.addSublayer(border)
    self.view.layer.masksToBounds = true
}

答案 1 :(得分:2)

<强>更新

我对我原来的解决方案有很多想法。

如果你要为UITextView创建一个底线,那么底线最好是文本视图本身的子视图,而不是它的超级视图。

最后,我找出了一个可以添加底线作为TextView本身的子视图的解决方案,当用户滚动TextView的文本时,底线不会移动。在视图控制器中,您还可以动态更改TextView的框架,底线也会粘在底部。

以下是参考代码:

import UIKit

class TextView: UITextView {

    var border: UIView
    var originalBorderFrame: CGRect
    var originalInsetBottom: CGFloat

    deinit {
        removeObserver(self, forKeyPath: "contentOffset")
    }

    override var frame: CGRect {
        didSet {
            border.frame = CGRectMake(0, frame.height+contentOffset.y-border.frame.height, frame.width, border.frame.height)
            originalBorderFrame  = CGRectMake(0, frame.height-border.frame.height, frame.width, border.frame.height);
        }
    }

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if keyPath == "contentOffset" {
            border.frame = CGRectOffset(originalBorderFrame, 0, contentOffset.y)
        }
    }

    func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
        border.backgroundColor = color
        border.frame = CGRectMake(0, frame.height+contentOffset.y-width, self.frame.width, width)
        originalBorderFrame = CGRectMake(0, frame.height-width, self.frame.width, width)
        textContainerInset.bottom = originalInsetBottom+width
    }
}

注意:由于我曾经在Objective-C中编写代码,所以我不熟悉Swift。上面的代码仅供您参考(尽管我已经测试了相应的Objective-C代码,并且它按预期工作):

  • 如您所见,没有初始化代码。我试图编写这样的代码,但它总是显示错误,我仍然不知道这一点。只需确保将以下代码添加到TextView初始化代码中:

    border = UIView()
    addSubview(border)
    originalInsetBottom = textContainerInset.bottom
    addObserver(self, forKeyPath: "contentOffset", options: .New, context: nil)
    
  • 我不熟悉可选值,换行,展开的概念......因此,如果需要,您应该在代码中添加?!

原始回答:

代码中的selfTextView吗?

如果是这样,当您将border添加为TextView的子图层时,border会在用户滚动TextView的文字时上下移动。< / p>

尝试添加border作为TextView超级视图的子图层,而不是TextView本身。

以下是代码(请注意,我将borderCALayer更改为UIView):

func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
     let border = UIView()
     border.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y+self.frame.height-width, textView.frame.width, width)
     border.backgroundColor = color
     self.superview!.insertSubview(border, aboveSubview: textView)
 }

以下是捕获:

enter image description here

PS。我建议你从宽度到高度更改第二个参数名称,因为宽度在这个上下文中是不明确的。

答案 2 :(得分:1)

以下行更好用:
border.autoresizingMask = [.flexibleWidth,.flexibleHeight]

extension UITextView { 
    func addBottomBorderWithColor(color: UIColor, height: CGFloat) {
        let border = UIView()
        border.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        border.frame = CGRect(self.frame.origin.x,    
        self.frame.origin.y+self.frame.height-height, self.frame.width, height)
        border.backgroundColor = color
        self.superview!.insertSubview(border, aboveSubview: self)
    }
}

答案 3 :(得分:0)

将掩码设置为false,然后只显示要显示的行的边界。

答案 4 :(得分:0)

有时候让事情彼此更加独立会更容易。

idcns <- c('HDI.Rank','Country');
`rownames<-`(value=NULL,reshape(
    df, ## input data.frame
    dir='l', ## specify that we want to transform from wide to long format
    idvar=idcns, ## all non-data columns must be identified as id columns
    timevar='year', ## specify the desired time variable column name in the long format
    varying=setdiff(names(df),idcns), ## unfortunately reshape() doesn't know the POE
    split=list(regexp='X',include=T,fixed=T) ## spec how to parse data col name and times
));
##    HDI.Rank     Country year     X
## 1       171 Afghanistan 1990 121.3
## 2        85     Albania 1990  35.1
## 3        83     Algeria 1990  39.9
## 4        34     Andorra 1990   7.5
## 5       149      Angola 1990 133.4
## 6        58 and Barbuda 1990  23.4
## 7       171 Afghanistan 1995 103.0
## 8        85     Albania 1995  29.1
## 9        83     Algeria 1995  36.4
## 10       34     Andorra 1995   5.2
## 11      149      Angola 1995 132.7
## 12       58 and Barbuda 1995  17.9
## 13      171 Afghanistan 2000  94.5
## 14       85     Albania 2000  23.2
## 15       83     Algeria 2000  33.9
## 16       34     Andorra 2000   3.9
## 17      149      Angola 2000 128.3
## 18       58 and Barbuda 2000  13.8
## 19      171 Afghanistan 2005  84.0
## 20       85     Albania 2005  18.2
## 21       83     Algeria 2005  28.8
## 22       34     Andorra 2005   3.1
## 23      149      Angola 2005 121.5
## 24       58 and Barbuda 2005  10.6
## 25      171 Afghanistan 2010  75.3
## 26       85     Albania 2010  14.8
## 27       83     Algeria 2010  23.5
## 28       34     Andorra 2010   2.4
## 29      149      Angola 2010 109.6
## 30       58 and Barbuda 2010   8.6
## 31      171 Afghanistan 2011  73.6
## 32       85     Albania 2011  14.2
## 33       83     Algeria 2011  22.8
## 34       34     Andorra 2011   2.4
## 35      149      Angola 2011 107.0
## 36       58 and Barbuda 2011   8.2
## 37      171 Afghanistan 2012  72.0
## 38       85     Albania 2012  13.8
## 39       83     Algeria 2012  22.2
## 40       34     Andorra 2012   2.3
## 41      149      Angola 2012 104.3
## 42       58 and Barbuda 2012   8.0
## 43      171 Afghanistan 2013  70.2
## 44       85     Albania 2013  13.3
## 45       83     Algeria 2013  21.6
## 46       34     Andorra 2013   2.2
## 47      149      Angola 2013 101.6
## 48       58 and Barbuda 2013   7.7

答案 5 :(得分:0)

请尝试以下可能对您有帮助的代码

func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
    let border = CALayer()
    border.backgroundColor = color.CGColor
    border.frame = CGRectMake(0, yourTextview.frame.origin.y+yourTextview.frame.size.height+1 , width, 1)
    self.view.layer.addSublayer(border)
    self.view.layer.masksToBounds = true
}

答案 6 :(得分:0)

我尝试了其他答案,这些答案要么难以实现,要么带有错误,但是,我找到了实现这一目标的简单也许是最好的方法

只需在您的UIView旁边添加一个UITextView,并将其高度设置为1(或您选择的2),设置约束,确保UIViewUITextView

所有这些操作都可以在情节提要中实现,因此在此不提供代码,因为可以将UIView替换为UIImageView,所以可以根据需要向UITextView添加胡子

:)