【问题标题】:Inverse UIlabel text color when its frame intersects an UIView当其框架与 UIView 相交时反转 UIlabel 文本颜色
【发布时间】:2013-03-10 09:50:39
【问题描述】:

您好我试图在标签矩形与 UIView 相交的情况下更改 UILabel 的文本颜色,我在想也许有一个属性或我可以使用的东西。如下图所示:

以前是否有人遇到过这个问题,或者我应该阅读什么来开始做这件事?

提前致谢

【问题讨论】:

    标签: iphone ios ipad core-graphics core-text


    【解决方案1】:

    好拼图!这是我要做的:

    1. 两个 UIView。让我们称一个为背景,另一个为progressBar。 progressBar 堆叠在背景顶部,在它们的共同 superview 上具有相同的 origin
    2. 它们有一个 UILabel 作为子视图,并且两个标签相对于它们的父级位于同一原点。背景是深色的backgroundColor,它的标签是浅色的textColor,而进度视图则相反。
    3. progressBar 的框架宽度比背景窄,并且有clipsToBounds==YES

    诀窍是,视图的来源相同,标签的来源相同,顶视图上有 clipsToBounds,一切都会看起来正确。

    将这两个视图拖放到一个新的 UIView 子类中,称为 RealCoolProgressView,并为其提供一个公共方法:

    -(void)setProgress:(float)progress 进度是一个从 0.0 到 1.0 的数字。该方法缩放progressBar宽度并设置both标签的文本@"Progress %f", progress*100

    【讨论】:

    • 这看起来很有趣,所以我构建了它并粘贴到这里:pastebin.com/ZCDmdpPq 它在一些快速测试中有效。
    • 嗯,是的,这将是一个不错的技巧,最快和最简单的一个。谢谢!!
    【解决方案2】:

    为任何正在寻找实际应用程序的人用 Swift 构建一个示例。关于这个 danh 的很好的指导 - 谢谢!


    import UIKit
    
    class CDSlideView: UIView {
    
        var leftBackView: UIView!
        var leftBackLabel: UILabel!
        var leftFrontView: UIView!
        var leftFrontLabel: UILabel!
    
        var rightBackView: UIView!
        var rightBackLabel: UILabel!
        var rightFrontView: UIView!
        var rightFrontLabel: UILabel!
    
        var foregroundView: UIView!
        var backgroundView: UIView!
    
        var slideGesture: UIPanGestureRecognizer!
    
        let lightColor: UIColor = UIColor.whiteColor()
        let darkColor: UIColor = UIColor.blueColor()
        let leftText: String = "Search"
        let rightText: String = "New"
    
        var viewWidth: CGFloat!
        var viewHeight: CGFloat!
        var leftOrigin: CGFloat!
        var rightOrigin: CGFloat!
        var foregroundPadding: CGFloat = 4
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            // Init variables variables
            viewWidth = self.frame.size.width
            viewHeight = self.frame.size.height
            leftOrigin = foregroundPadding / 2
            rightOrigin = (viewWidth - foregroundPadding) / 2 + foregroundPadding / 2
    
            backgroundView = UIView()
            backgroundView.frame = CGRectMake(0, 0, viewWidth, viewHeight)
            backgroundView.layer.cornerRadius = backgroundView.frame.size.height / 2
            self.addSubview(backgroundView)
    
            leftBackView = UIView()
            leftBackView.frame = CGRectMake(0, 0, backgroundView.frame.size.width / 2, backgroundView.frame.size.height)
            self.backgroundView.addSubview(leftBackView)
    
            leftBackLabel = UILabel()
            leftBackLabel.frame = CGRectMake(0, 0, leftBackView.frame.size.width, leftBackView.frame.size.height)
            leftBackLabel.font = UIFont.systemFontOfSize(13, weight: UIFontWeightSemibold)
            leftBackLabel.backgroundColor = UIColor.clearColor()
            leftBackLabel.lineBreakMode = .ByClipping
            leftBackLabel.textAlignment = .Center
            self.leftBackView.addSubview(leftBackLabel)
    
            rightBackView = UIView()
            rightBackView.frame = CGRectMake(backgroundView.frame.size.width / 2, 0, backgroundView.frame.size.width / 2, backgroundView.frame.size.height)
            self.backgroundView.addSubview(rightBackView)
    
            rightBackLabel = UILabel()
            rightBackLabel.frame = CGRectMake(0, 0, rightBackView.frame.size.width, rightBackView.frame.size.height)
            rightBackLabel.font = UIFont.systemFontOfSize(13, weight: UIFontWeightSemibold)
            rightBackLabel.backgroundColor = UIColor.clearColor()
            rightBackLabel.lineBreakMode = .ByClipping
            rightBackLabel.textAlignment = .Center
            self.rightBackView.addSubview(rightBackLabel)
    
            foregroundView = UIView()
            foregroundView.frame = CGRectMake(foregroundPadding / 2, foregroundPadding / 2, (backgroundView.frame.size.width - foregroundPadding) / 2, backgroundView.frame.size.height - foregroundPadding)
            foregroundView.clipsToBounds = true
            foregroundView.layer.cornerRadius = (foregroundView.frame.size.height - foregroundPadding / 2) / 2
            self.addSubview(foregroundView)
    
            slideGesture = UIPanGestureRecognizer(target: self, action: #selector(CDSlideView.slideAction))
            self.foregroundView.addGestureRecognizer(slideGesture)
    
            leftFrontView = UIView()
            leftFrontView.frame = CGRectMake(0, 0, backgroundView.frame.size.width / 2, backgroundView.frame.size.height)
            self.foregroundView.addSubview(leftFrontView)
    
            leftFrontLabel = UILabel()
            leftFrontLabel.font = UIFont.systemFontOfSize(13, weight: UIFontWeightSemibold)
            leftFrontLabel.backgroundColor = UIColor.clearColor()
            leftFrontLabel.translatesAutoresizingMaskIntoConstraints = false
            leftFrontLabel.lineBreakMode = .ByClipping
            leftFrontLabel.textAlignment = .Center
            self.leftFrontView.addSubview(leftFrontLabel)
    
            let leftFrontLabelLeadingConstraint = NSLayoutConstraint(item: leftFrontLabel, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1, constant: self.backgroundView.frame.origin.x)
            self.addConstraint(leftFrontLabelLeadingConstraint)
    
            let leftFrontLabelTopConstraint = NSLayoutConstraint(item: leftFrontLabel, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: self.backgroundView.frame.origin.y)
            self.addConstraint(leftFrontLabelTopConstraint)
    
            let leftFrontLabelWidthConstraint = NSLayoutConstraint(item: leftFrontLabel, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: leftFrontView.frame.size.width)
            self.addConstraint(leftFrontLabelWidthConstraint)
    
            let leftFrontLabelHeightConstraint = NSLayoutConstraint(item: leftFrontLabel, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: leftFrontView.frame.size.height)
            self.addConstraint(leftFrontLabelHeightConstraint)
    
            rightFrontView = UIView()
            rightFrontView.frame = CGRectMake(backgroundView.frame.size.width / 2, 0, backgroundView.frame.size.width / 2, backgroundView.frame.size.height)
            self.foregroundView.addSubview(rightFrontView)
    
            rightFrontLabel = UILabel()
            rightFrontLabel.font = UIFont.systemFontOfSize(13, weight: UIFontWeightSemibold)
            rightFrontLabel.backgroundColor = UIColor.clearColor()
            rightFrontLabel.translatesAutoresizingMaskIntoConstraints = false
            rightFrontLabel.lineBreakMode = .ByClipping
            rightFrontLabel.textAlignment = .Center
            self.rightFrontView.addSubview(rightFrontLabel)
    
            let rightFrontLabelTrailingConstraint = NSLayoutConstraint(item: self, attribute: .Trailing, relatedBy: .Equal, toItem: rightFrontLabel, attribute: .Trailing, multiplier: 1, constant: self.backgroundView.frame.origin.x)
            self.addConstraint(rightFrontLabelTrailingConstraint)
    
            let rightFrontLabelTopConstraint = NSLayoutConstraint(item: rightFrontLabel, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: self.backgroundView.frame.origin.y)
            self.addConstraint(rightFrontLabelTopConstraint)
    
            let rightFrontLabelWidthConstraint = NSLayoutConstraint(item: rightFrontLabel, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: rightFrontView.frame.size.width)
            self.addConstraint(rightFrontLabelWidthConstraint)
    
            let rightFrontLabelHeightConstraint = NSLayoutConstraint(item: rightFrontLabel, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: rightFrontView.frame.size.height)
            self.addConstraint(rightFrontLabelHeightConstraint)
    
            let leftTapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CDSlideView.leftTap(_:)))
            self.leftBackView.addGestureRecognizer(leftTapGesture)
    
            let rightTapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CDSlideView.rightTap(_:)))
            self.rightBackView.addGestureRecognizer(rightTapGesture)
    
            self.setLabelText(leftText, rightText: rightText)
            self.setLightColor(lightColor)
            self.setDarkColor(darkColor)
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        // MARK: Setup
        func setLightColor(lightColor: UIColor) {
            let lightColor = lightColor
            self.foregroundView.backgroundColor = lightColor
            self.leftBackLabel.textColor = lightColor
            self.rightBackLabel.textColor = lightColor
        }
    
        func setDarkColor(darkColor: UIColor) {
            let darkColor = darkColor
            self.backgroundView.backgroundColor = darkColor
            self.leftFrontLabel.textColor = darkColor
            self.rightFrontLabel.textColor = darkColor
        }
    
        func setLabelText(leftText: String, rightText: String) {
            self.leftFrontLabel.text = leftText
            self.leftBackLabel.text = leftText
            self.rightFrontLabel.text = rightText
            self.rightBackLabel.text = rightText
        }
    
        // MARK: Actions
        func slideAction(sender: UIPanGestureRecognizer) {
            if sender.state == .Began || sender.state == .Changed {
                let translation = sender.translationInView(self)
    
                // Calculate where the user is trying to drag
                var newCenter: CGPoint = CGPointMake(sender.view!.center.x + translation.x, sender.view!.center.y)
    
                // Limit bounds & update center
                newCenter.x = max(self.frame.size.width * 0.25 + foregroundPadding / 2, newCenter.x)
                newCenter.x = min(self.frame.size.width * 0.75 - foregroundPadding / 2, newCenter.x)
    
                // Set new center
                sender.view!.center = newCenter
                sender.setTranslation(CGPointMake(0,0), inView: self)
            } else if sender.state == .Ended {
                let senderVCX = sender.view?.center.x
    
                // Snap to side
                if senderVCX <= viewWidth / 2 {
                    print("called left")
                    sender.view?.frame.origin.x = self.leftOrigin
                } else {
                    print("called right")
                    sender.view?.frame.origin.x = self.rightOrigin
                }
            }
        }
    
        func leftTap(sender: UITapGestureRecognizer) {
            UIView.animateWithDuration(0.05) {
                self.foregroundView.frame.origin.x = self.leftOrigin
            }
        }
    
        func rightTap(sender: UITapGestureRecognizer) {
            UIView.animateWithDuration(0.05) {
                self.foregroundView.frame.origin.x = self.rightOrigin
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我建议你看看这些方法:

      您可以通过检查 NSString 的大小来检查您的字符串有多少与视图重叠,使用以下方法:

      [yourString sizeWithFont:yourFont constrainedToSize:maximumAllowedSize];
      

      然后您可以使用 NSMutableAttributedString 将标签字符串的一部分设置为一种颜色,而将后一部分设置为另一种颜色。

      //Just an example usage 
      //It sets the color of characters starting from 3 to the end to blue
      [str addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(3, str.length)];
      
      
      //Now you have to set your string as attributed text just like below
      //UILabels now support attributed strings by default which is quite handy
      
      [yourLabel setAttributedString:str];
      

      【讨论】:

      • 这不适用于仅部分覆盖的字母。我认为@Florik 需要使用 CoreGraphics 和自定义 drawRect 做一些聪明的事情来获得他正在寻找的效果。
      • 是的,你是对的,他需要自己画弦来支持部分弦。
      【解决方案4】:

      看看this tutorial for creating alpha masks with text。使用这种技术,您可以实现一个标准进度条,该进度条在前景和背景视图中移动,以实现您想要的效果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-08
        • 2014-01-25
        • 2013-05-17
        • 2011-11-13
        相关资源
        最近更新 更多