仅为部分 UIView 设置背景颜色

Posted

技术标签:

【中文标题】仅为部分 UIView 设置背景颜色【英文标题】:Set background color for only part of UIView 【发布时间】:2013-08-05 17:27:41 【问题描述】:

我希望 UIView 的底部(不是一半)与顶部的颜色不同。

我想知道我是否应该创建一个 CGRect 然后给它上色?这是在正确的轨道上吗?

- (void)drawRect:(CGRect)rect  

    CGRect aRect = CGRectMake(x, y, width, height);

    // Fill the rectangle with grey
    [[UIColor greyColor] setFill];
    UIRectFill( rect );

【问题讨论】:

你需要创建一个 UIView 子类来覆盖 drawRect 方法。 如果有帮助,请批准一个答案。 【参考方案1】:

是的,因为您已经覆盖了 drawRect 方法,所以可以这样做。

- (void)drawRect:(CGRect)rect  

    CGRect topRect = CGRectMake(0, 0, rect.size.width, rect.size.height/2.0);
    // Fill the rectangle with grey
    [[UIColor greyColor] setFill];
    UIRectFill( topRect );

    CGRect bottomRect = CGRectMake(0, rect.size.height/2.0, rect.size.width, rect.size.height/2.0);
    [[UIColor redColor] setFill];
    UIRectFill( bottomRect );


根据需要更改框架内的值。

【讨论】:

当我将您的代码放入我的 .m 文件中时,没有任何反应。 drawRect 是自动调用的,对吧? 你把它放在哪个 .m 文件中?是的,它是自动调用的,但是 drawRect 是 UIView 类的一个方法。你真的要覆盖 UIView 吗? 就像我说的,drawRect是UIView类的一个方法。您必须创建一个覆盖 UIView 的类,并将其添加为 viewcontroller 主视图的子视图【参考方案2】:

使用 Swift 5.1 和 ios 13,您可以选择以下两种方式之一来解决您的问题。


#1。使用UIRectFill(_:) 函数在UIView 子类中使用UIColor 实例绘制并填充指定的CGRect 实例

UIKit 提供了一个UIRectFill(_:) 函数。 UIRectFill(_:) 有以下声明:

func UIRectFill(_ rect: CGRect)

用当前颜色填充指定的矩形。

以下 Playground 代码展示了如何使用UIRectFill(_:)

import UIKit
import PlaygroundSupport

class CustomView: UIView 

    override init(frame: CGRect) 
        super.init(frame: frame)

        backgroundColor = UIColor.green
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override func draw(_ rect: CGRect) 
        super.draw(rect)

        let bottomRect = CGRect(
            origin: CGPoint(x: rect.origin.x, y: rect.height / 2),
            size: CGSize(width: rect.size.width, height: rect.size.height / 2)
        )
        UIColor.red.set()
        UIRectFill(bottomRect)
    



let view = CustomView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
PlaygroundPage.current.liveView = view

#2。使用CGContextfill(_:) 方法在UIView 子类中使用UIColor 实例绘制并填充指定的CGRect 实例

CGContext 有一个名为fill(_:) 的方法。 fill(_:) 有以下声明:

func fill(_ rect: CGRect)

使用当前图形状态下的填充颜色绘制包含在提供的矩形内的区域。

以下 Playground 代码展示了如何使用fill(_:)

import UIKit
import PlaygroundSupport

class CustomView: UIView 

    override init(frame: CGRect) 
        super.init(frame: frame)

        backgroundColor = UIColor.green
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override func draw(_ rect: CGRect) 
        super.draw(rect)

        let bottomRect = CGRect(
            origin: CGPoint(x: rect.origin.x, y: rect.height / 2),
            size: CGSize(width: rect.size.width, height: rect.size.height / 2)
        )
        UIColor.red.set()
        guard let context = UIGraphicsGetCurrentContext() else  return 
        context.fill(bottomRect)
    



let view = CustomView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
PlaygroundPage.current.liveView = view

【讨论】:

#1 和 #2 哪个更好?【参考方案3】:

您还可以将 CALayer 作为子层添加到您的视图中。 包括 CoreGraphics 和 QuartzCore 框架,并在您的 drawRect 方法中创建具有所需形状因子的 CGRect。 使用 rect 实例化一个 CALayer,并使用 [self.layer addSublayer:theLayer] 将其添加到视图层。 在添加之前使用 CALayer 的 -setBackgroundColor: 方法。

如果这是在 View Controller 而不是 View 子类中,请在 viewDidLoad 方法中执行完全相同的操作。

布莱恩

【讨论】:

你的理论很清楚,但给出一些代码对我有帮助。【参考方案4】:

您可以使用此代码。请根据您的需要更改 CGRect。

- (void)drawRect:(CGRect)rect

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGRect topView = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 2);
    CGRect bottomView = CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 2, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 2);

    UIColor * grayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0];

    CGContextSetFillColorWithColor(context, grayColor.CGColor);
    CGContextFillRect(context, bottomView);

    CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
    CGContextFillRect(context, topView);

以下链接可能对您有更多帮助。 http://www.raywenderlich.com/32925/core-graphics-tutorial-shadows-and-gloss

【讨论】:

【参考方案5】:

你可以做一个 CGRect 并剪裁一部分来填充。

但是为什么不尝试两个不同的 UIView 并排放置呢?

婆罗门

【讨论】:

【参考方案6】:

覆盖 UIView 子类的 drawRect 方法。以下代码将使视图的上半部分变为黑色,视图的下半部分变为红色。

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect

    // Top View
    CGRect topRect = CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds), CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds);
    [[UIColor blackColor] setFill];
    UIRectFill(topRect);

    // Bottom View
    CGRect bottomRect = CGRectGetMinX(self.bounds), CGRectGetMidY(self.bounds), CGRectGetMaxX(self.bounds), CGRectGetMidY(self.bounds);
    [[UIColor redColor] setFill];
    UIRectFill(bottomRect);

注意:您也只能在子类化 UIView 时覆盖 drawRect: 方法。根据您的评论观点,我感觉这不是您在做的事情。

【讨论】:

当我实现你的代码时,我得到一个错误,“在对象类型 [myUIView] 上找不到属性'frame'”... 你在继承 UIView 吗?如果是这样,那么您应该可以访问 frame 属性。 另外,我认为发布的代码不正确。你想用self.bounds定义topRect和bottomRect,而不是self.frame,因为frame是根据superview的坐标空间,而bounds是根据view的坐标空间,这就是你的想要自定义绘图。 @ZevEisenberg 这不是错误的,在某些情况下边界很有用。但是在这种情况下,当 UIView 子类被实例化时,框架被设置为其父视图。 在此使用 frame 是不正确的,只要视图的原点不在其父视图的坐标空间中的 0,0 处,或者当视图上存在可能导致 @ 的变换时987654327@ 和 bounds 是不同的。

以上是关于仅为部分 UIView 设置背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

UIView 背景颜色比 UICollectionView 背景颜色深

无法从 Controller 设置 UIView 背景颜色

设置 UIView 的背景颜色会增加内存使用量

在 xib 中带有 alpha 的 UIView 背景颜色

Swift - 设置UIView的背景色和背景图片

如何在 Xamarin 表单中使用 MVVM 仅为集合视图中的选定框架设置颜色?