如何在 Swift 中创建独特的形状或 UIView

Posted

技术标签:

【中文标题】如何在 Swift 中创建独特的形状或 UIView【英文标题】:How to create unique shapes or UIViews in Swift 【发布时间】:2016-01-13 22:05:50 【问题描述】:

我对在 Swift 中绘图一无所知,但我希望创建与正方形略有不同的应用背景的一部分。请参阅下图了解我正在尝试制作的内容:

这个想法是,它将位于屏幕的顶部,只不过是一个背景。它会延伸到屏幕的一半。然后我将在顶部添加一个图像等。我需要正方形底部的点始终位于屏幕中间。

我可以通过代码在 Swift 中制作这个形状/UIView 吗?如果有,怎么做?

或者,将其创建为图像并这样做会更好吗?

【问题讨论】:

【参考方案1】:

我可以通过代码在 Swift 中制作这个形状/UIView 吗?如果有,怎么做?

视图总是矩形的,但是视图的内容可以是任何形状,而且它的背景可以是透明的,所以视图的可见部分可以是任何你可以绘制的东西。

ios 中有很多方法来绘制一些东西。通常最好从适合您的***别的工具开始,当您需要更多控制权时,再向下移动到较低级别。考虑到这一点,我建议首先创建一个使用UIBezierPath 绘制五边形的视图。 (Swift 5) 代码非常简单:

class PentagonView : UIView 
    override init(frame: CGRect) 
        super.init(frame: frame)
        backgroundColor = UIColor.clear
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        backgroundColor = UIColor.clear
    

    override func draw(_ rect: CGRect) 
        let size = self.bounds.size
        let h = size.height * 0.85      // adjust the multiplier to taste

        // calculate the 5 points of the pentagon
        let p1 = self.bounds.origin
        let p2 = CGPoint(x:p1.x + size.width, y:p1.y)
        let p3 = CGPoint(x:p2.x, y:p2.y + h)
        let p4 = CGPoint(x:size.width/2, y:size.height)
        let p5 = CGPoint(x:p1.x, y:h)

        // create the path
        let path = UIBezierPath()
        path.move(to: p1)
        path.addLine(to: p2)
        path.addLine(to: p3)
        path.addLine(to: p4)
        path.addLine(to: p5)
        path.close()

        // fill the path
        UIColor.red.set()
        path.fill()
    

现在您可以在 UI 中的任何位置使用该视图:

如果您想在坐标 (100, 200) 处向视图控制器的主视图添加 150x150 像素 PentagonView,您可以在 viewDidLoad() 中添加以下内容:

let pg = PentagonView(frame:CGRect(x:100, y:200, width:150, height:150))
self.view.addSubview(pg)

或者,您也可以通过放入大小合适的UIView,然后将其类更改为PentagonView,将PentagonView 添加到故事板中的某个视图。

或者,将其创建为图像并这样做会更好吗?

如果您已经完全描述了您的要求,那么不,我不这么认为:图像本身可能会比绘制它的代码大很多,而我上面给出的代码将适用于您选择的任何尺寸。另一方面,如果您要添加许多复杂的细节,并且图像只需要以一种尺寸显示,那么在绘图程序中创建一次并将其存储为图像可能会更容易.就像我上面说的,iOS 中有很多绘图选项;你选择哪一个应该根据你的需要来决定。

【讨论】:

谢谢!我可以理解每一步,所以感谢 cmets!我创建了一个新的 .Swift 文件,并添加了该代码,然后在 VC 的 .Swift 文件中,在viewDidLoad 方法中,我添加了let BG = PentagonView(frame: CGRect(origin: CGPoint(), size: CGSize(width: 250, height: 250))) - 但是当我运行该应用程序时,没有任何显示。 Xcode 中没有错误,只是没有显示。 @Nick89 抱歉,如果不清楚——我在操场上编写了上面的代码,你真正需要做的就是实例化视图。要在应用程序中使用,您需要在某处创建PentagonView 的实例,然后将其添加到视图层次结构中。最简单的方法可能是在情节提要中的一个视图中添加PentagonView(如果您正在使用一个视图)。 嗨,对不起,我没有关注 :( 在如何设置它之前,我从来没有做过任何明智的绘图。我将代码添加到一个名为 CreateShape.swift 的新文件中,我需要将它添加到我的视图控制器,它有一个连接到它的文件,名为mainVC.swift。你能帮我用代码告诉我如何设置它吗?我希望在绘图方面做更多事情,所以很想了解怎么做!提前致谢 @Nick89 你应该看看UIView reference page 的创建视图部分。在您的 let BG = ... 行之后,添加另一行:self.view.addSubview(BG)。那应该做你想做的,因为self.view 是视图控制器的主视图。您调用addSubview()BG 添加为该视图的子视图。如果要更改PentagonView 的位置或大小,请更改创建BG 的框架矩形。 啊,我明白了!非常感谢您的帮助!【参考方案2】:

Caleb 的答案已更新为 Swift 5

class PentagonView : UIView 
    override init(frame: CGRect) 
        super.init(frame: frame)
        backgroundColor = .clear
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        backgroundColor = .clear
    

    override func draw(_ rect: CGRect) 
        let size = self.bounds.size
        let h = size.height * 0.85      // adjust the multiplier to taste

        // calculate the 5 points of the pentagon
        let p1 = self.bounds.origin
        let p2 = CGPoint(x:p1.x + size.width, y:p1.y)
        let p3 = CGPoint(x:p2.x, y:p2.y + h)
        let p4 = CGPoint(x:size.width/2, y:size.height)
        let p5 = CGPoint(x:p1.x, y:h)

        // create the path
        let path = UIBezierPath()
        path.move(to: p1)
        path.addLine(to: p2)
        path.addLine(to: p3)
        path.addLine(to: p4)
        path.addLine(to: p5)
        path.close()

        // fill the path
        UIColor.red.set()
        path.fill()
    

【讨论】:

【参考方案3】:

解决此问题的最佳方法不是创建视图 (UIView),而是创建层 (CAShapeLayer)。您可以从路径创建 CAShapeLayer,从而使用矢量(而不是位图)描述您的形状。

有很多关于 CAShapeLayer 的教程将向您展示实现此目的的代码。

【讨论】:

【参考方案4】:

如果您从形状文件加载图像到 UIImageView 上可能会是最好的,特别是如果它只是一个背景。然后,您可以将视图的底部限制在应用程序的中间。但是,您也可以对视图的 CALayer 属性进行一些调整以实现您的效果。

【讨论】:

对于图像,您必须针对不同的屏幕尺寸和分辨率维护不同版本的资产。这在代码中很容易做到,并且完全避免了这个问题。 @NoahWitherspoon 我认为像这样的完全红色的形状可以合理地按比例缩小,而 Xcode 本身不会有太大的质量损失。

以上是关于如何在 Swift 中创建独特的形状或 UIView的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS Swift4 中创建这个圆形?

在 Swift 中创建自定义 UIView 并显示为弹出窗口

在 Swift 中创建自定义(八角形)UIButton 的最佳方法

Swift - 如何在 MVC 中正确构建按钮?

如何在 swift 中创建新闻提要 UI

是否可以在 Swift 中创建具有 Self 或关联类型要求的通用计算属性,如果可以,如何?