How to display image in diamond shape in swift?
Asked Answered
A

3

5

Image

I want to display images in diamond shape when I am giving width and height 120 and apply the corner radiu. I am getting diamond shape approximately but not getting exact diamond shape so any one suggest me it helpful to me.

self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2
self.imageView.clipsToBounds = true
Alvertaalves answered 29/6, 2016 at 4:57 Comment(3)
can you paste your code here.Gentry
self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2 self.imageView.clipsToBounds = trueAlvertaalves
i applied above code and i mentioned width and height equals to 120Alvertaalves
N
24

If you have an image view and want to crop it to a diamond (rhombus) shape, you should:

  • Create UIBezierPath in diamond shape;
  • Use that as the path of a CAShapeLayer;
  • Set that CAShapeLayer as the mask of the UIImageView's layer

In Swift 3 and later, that might look like:

extension UIView {
    func addDiamondMask(cornerRadius: CGFloat = 0) {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: bounds.midX, y: bounds.minY + cornerRadius))
        path.addLine(to: CGPoint(x: bounds.maxX - cornerRadius, y: bounds.midY))
        path.addLine(to: CGPoint(x: bounds.midX, y: bounds.maxY - cornerRadius))
        path.addLine(to: CGPoint(x: bounds.minX + cornerRadius, y: bounds.midY))
        path.close()

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = UIColor.white.cgColor
        shapeLayer.strokeColor = UIColor.white.cgColor
        shapeLayer.lineWidth = cornerRadius * 2
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.lineCap = kCALineCapRound

        layer.mask = shapeLayer
    }
}

So, just call addDiamondMask(cornerRadius:) (where the cornerRadius is optional), on your image view.

imageView.addDiamondMask()

That yields:

enter image description here

For Swift 2 rendition, see previous revision of this answer.


An alternate algorithm for rounding of corners might be:

extension UIView {
    func addDiamondMask(cornerRadius: CGFloat = 0) {
        let path = UIBezierPath()

        let points = [
            CGPoint(x: bounds.midX, y: bounds.minY),
            CGPoint(x: bounds.maxX, y: bounds.midY),
            CGPoint(x: bounds.midX, y: bounds.maxY),
            CGPoint(x: bounds.minX, y: bounds.midY)
        ]

        path.move(to: point(from: points[0], to: points[1], distance: cornerRadius, fromStart: true))
        for i in 0 ..< 4 {
            path.addLine(to: point(from: points[i], to: points[(i + 1) % 4], distance: cornerRadius, fromStart: false))
            path.addQuadCurve(to: point(from: points[(i + 1) % 4], to: points[(i + 2) % 4], distance: cornerRadius, fromStart: true), controlPoint: points[(i + 1) % 4])
        }
        path.close()

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = UIColor.white.cgColor
        shapeLayer.strokeColor = UIColor.clear.cgColor

        layer.mask = shapeLayer
    }

    private func point(from point1: CGPoint, to point2: CGPoint, distance: CGFloat, fromStart: Bool) -> CGPoint {
        let start: CGPoint
        let end: CGPoint

        if fromStart {
            start = point1
            end = point2
        } else {
            start = point2
            end = point1
        }
        let angle = atan2(end.y - start.y, end.x - start.x)
        return CGPoint(x: start.x + distance * cos(angle), y: start.y + distance * sin(angle))
    }

}

Here I'm doing quad bezier in the corners, but I think the effect for rounded corners is slightly better than the above if the diamond is at all elongated.

Anyway, that yields:

enter image description here

Ningpo answered 29/6, 2016 at 5:9 Comment(2)
Wow its awsome... But its not taking corner radius.. How can i make corners rounded in this. ?Lansquenet
@SagarThukral - See revised answer for example of how to round the corners.Ningpo
L
0

SWIFT 5

extension UIView {
    func addDiamondMask(cornerRadius: CGFloat = 0) {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: bounds.midX, y: bounds.minY + cornerRadius))
        path.addLine(to: CGPoint(x: bounds.maxX - cornerRadius, y: bounds.midY))
        path.addLine(to: CGPoint(x: bounds.midX, y: bounds.maxY - cornerRadius))
        path.addLine(to: CGPoint(x: bounds.minX + cornerRadius, y: bounds.midY))
        path.close()

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = UIColor.white.cgColor
        shapeLayer.strokeColor = UIColor.white.cgColor
        shapeLayer.lineWidth = cornerRadius * 2
        shapeLayer.lineJoin = .round
        shapeLayer.lineCap = .round

        layer.mask = shapeLayer
    }
}
Lindsylindy answered 6/8, 2019 at 11:27 Comment(0)
Q
0

If your view uses many screens or views so sometimes you make diamond shape views and sometimes square views, I have made an IBDesignable Diamond shape UIView class.

import Foundation
import UIKit

@IBDesignable
public class DiamondView: UIView {
    
    private var _cornerRadius: CGFloat = 0
    private var _isDiamondShape: Bool = false
    
    @IBInspectable override var cornerRadius: CGFloat {
        get {
            return _cornerRadius
        }
        set {
            _cornerRadius = newValue
            setNeedsLayout()
        }
    }
    
    @IBInspectable var isDiamondShape: Bool {
        get {
            return _isDiamondShape
        }
        set {
            _isDiamondShape = newValue
            setNeedsLayout()
        }
    }
    
    override public func layoutSubviews() {
        super.layoutSubviews()
        if isDiamondShape {
            addDiamondMask()
        } else {
            layer.mask = nil
        }
    }
    
    private func addDiamondMask() {
        let path = UIBezierPath()
        
        let points = [
            CGPoint(x: bounds.midX, y: bounds.minY),
            CGPoint(x: bounds.maxX, y: bounds.midY),
            CGPoint(x: bounds.midX, y: bounds.maxY),
            CGPoint(x: bounds.minX, y: bounds.midY)
        ]
        
        path.move(to: point(from: points[0], to: points[1], distance: _cornerRadius, fromStart: true))
        for i in 0..<4 {
            path.addLine(to: point(from: points[i], to: points[(i + 1) % 4], distance: _cornerRadius, fromStart: false))
            path.addQuadCurve(to: point(from: points[(i + 1) % 4], to: points[(i + 2) % 4], distance: _cornerRadius, fromStart: true), controlPoint: points[(i + 1) % 4])
        }
        path.close()
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = UIColor.white.cgColor
        shapeLayer.strokeColor = UIColor.clear.cgColor
        
        layer.mask = shapeLayer
    }
    
    private func point(from point1: CGPoint, to point2: CGPoint, distance: CGFloat, fromStart: Bool) -> CGPoint {
        let start: CGPoint
        let end: CGPoint
        
        if fromStart {
            start = point1
            end = point2
        } else {
            start = point2
            end = point1
        }
        let angle = atan2(end.y - start.y, end.x - start.x)
        return CGPoint(x: start.x + distance * cos(angle), y: start.y + distance * sin(angle))
    }
}
Qualified answered 25/4 at 4:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.