Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create unique shapes or UIViews in Swift

Tags:

ios

swift

uiview

I don't really have any knowledge of drawing in Swift, but I'm looking to create part of my app background that's slightly different to a square. See the image below for what I'm trying to make:

enter image description here

The idea is that this will sit at the top of the screen, and be nothing more than a background. It'll stretch half way down the screen. I'll then add an image over the top etc. I would need the point at the bottom of the square to always sit in the middle of the screen.

Can I make this shape/UIView in Swift by code? And if so, how?

Or, is it better to just create this as an image and do it that way?

like image 393
Nick89 Avatar asked Jan 13 '16 22:01

Nick89


People also ask

What are the built-in 2D shapes in SwiftUI?

SwiftUI comes with quite a number of built-in 2D shapes such as Rectangle, Circle, Ellipse, Capsule, RoundedRectangle etc. If all these are not enough to fulfil your needs, you can also create your own custom shapes by using Path

What is innerratio parameter in SwiftUI view?

So, the following code is an example on creating a few star shapes and arranged in a HStack in a SwiftUI view. The parameter innerRatio is to control the sharpness of the star's corners, the lower the value the sharper it is. Please leave us your comments below, if you find any errors or mistakes with this post.

What are the different types of iOS views?

Any iOS app has a many views. Those views needs four values specified in order to be displayed: x, y, width, height. There are three different ways of building these views: Storyboards, Nib files and Programmatically.

How do I add purelayout to my Swift project?

There are various ways to add PureLayout to your Swift project. I’m using cocoapods, a dependency manager for Swift and Objective-C projects. It requires a file named Podfile that looks like this: Next run the following command to install dependencies, PureLayout in this case: This command will create a new project file that ends in .xcworkspace.


3 Answers

Can I make this shape/UIView in Swift by code? And if so, how?

Views are always rectangular, but a view's content can be any shape at all and it's background can be transparent, so the visible part of a view can be anything you can draw.

There are a lot of ways to draw something in iOS. It's usually best to start with the highest level tool that'll work for you and move down to a lower level when you need more control. With that in mind, I'd suggest starting by creating a view that draws your pentagon using a UIBezierPath. The (Swift 5) code for this is very simple:

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()
    }
}

And now you can use that view anywhere in your UI: PentagonView

If you want to add a 150x150px PentagonView to your view controller's main view at coordinates (100, 200), you could put the following in viewDidLoad():

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

Or, you could also add a PentagonView to some view in your storyboard by dropping in a UIView of the right size and then changing it's class to PentagonView.

Or, is it better to just create this as an image and do it that way?

If you've fully described your requirement, then no, I don't think so: the image itself will probably be a lot larger than the code that draws it, and the code that I've given above will work at any size you choose. On the other hand, if you're going to add a lot of complex detail, and if the image only needs to appear at one size, then it might be easier to create it once in a drawing program and store that work as an image. Like I said above, there are a lot of options for drawing in iOS; which you choose should be determined by your needs.

like image 60
Caleb Avatar answered Oct 16 '22 19:10

Caleb


Caleb's answer updated to 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()
    }
}
like image 6
Gustavo Vollbrecht Avatar answered Oct 16 '22 17:10

Gustavo Vollbrecht


The best way to tackle this is not by creating a view (UIView) but a layer (CAShapeLayer). You can create a CAShapeLayer from a path, thus describing your shape with vectors (as opposed to a bitmap).

There are many tutorials about CAShapeLayer that will show you code for achieving this.

like image 3
Clafou Avatar answered Oct 16 '22 18:10

Clafou