如何创建对角线切割视图以在配置文件屏幕中使用?

Posted

技术标签:

【中文标题】如何创建对角线切割视图以在配置文件屏幕中使用?【英文标题】:How can I create diagonal cut view to use in profile screen? 【发布时间】:2017-10-03 06:41:39 【问题描述】:

我有一个屏幕,我需要在 imageview 之后在其中添加对角线切割视图。

这是我需要做的截图,

所以请帮助我创建这种视图。

我已推荐this

和this 问题。

但我想知道是否有更可靠的方法来实现这一点。

提前致谢。

【问题讨论】:

看到这个***.com/questions/26339943/… 【参考方案1】:

为此,您可以将视图添加到情节提要中,并将视图的类设置为自定义类,这会将视图的布局更改为对角线切割。

自定义类应如下所示:

//
//  CustomShapeView.swift
//
//
//  Created by Umar Farooque on 17/09/17.
//  Copyright © 2017 ufocorp. All rights reserved.
//

import UIKit
@IBDesignable
class CustomShapeView: UIView 

    @IBInspectable var color : UIColor? = UIColor.gray 
        didSet 
            //            self.layer.backgroundColor = self.color?.cgColor
        

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

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

    

    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) 
        // Drawing code
        //get the size of the view
        let size = self.bounds.size
        //get 4 points for the shape layer
        let p1 = self.bounds.origin
        let p2 = CGPoint(x: p1.x + size.width, y: p1.y)
        let p3 = CGPoint(x: p2.x, y: size.height)
        let p4 = CGPoint(x: p1.x, y: size.height - 30)

        //create the path
        let path = UIBezierPath()
        path.move(to: p1)
        path.addLine(to: p2)
        path.addLine(to: p3)
        path.addLine(to: p4)
        path.close()
        (color ?? UIColor.gray).set()
        path.fill()

    


结果会是这样的:

【讨论】:

好的。让我检查一下【参考方案2】:

我使用一些响应(在我的情况下是一个三角形)用点击手势:

类三角视图


protocol TriangleViewProtocol 
    func shapeTapped()
    func outShapeTapped(touch: UITouch)


class TriangleView : UIView 
    var color: CGColor = UIColor.red.cgColor

    var delegate: TriangleViewProtocol?

    override init(frame: CGRect) 
        super.init(frame: frame)
        self.backgroundColor = UIColor.clear
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    

    override func draw(_ rect: CGRect) 
        // Draw a shape with 3 sides
        self.layer.sublayers?.forEach( $0.removeFromSuperlayer() )
        do 
            let rectangleLayer = try getPathPayer(arrPathPoints: [
                CGPoint(x: rect.maxX, y: rect.minY),
                CGPoint(x: rect.maxX, y: rect.maxY),
                CGPoint(x: rect.minX, y: rect.maxY)
                ])
            self.layer.addSublayer(rectangleLayer)
         catch 
            debugPrint(error)
        
    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        // Get tap and calculate what side of view is touched
        guard let touch = touches.first,
            let sublayers = self.layer.sublayers as? [CAShapeLayer]else  return 
        let point = touch.location(in: self)
        for layer in sublayers
            // On my case I need to get two actions
            // one if user tap on blue side
            // and other outside blue for send this actions to bellow views
            if let path = layer.path, path.contains(point) 
                self.delegate?.shapeTapped()
            else 
                self.delegate?.outShapeTapped(touch: touch)
            
        
    

    func getPathPayer(arrPathPoints:[CGPoint]) throws -> CAShapeLayer 
        enum PathError : Error
            case moreThan2PointsNeeded
        

        guard arrPathPoints.count > 2 else 
            throw PathError.moreThan2PointsNeeded
        

        let lineColor = UIColor.black
        let lineWidth: CGFloat = 2
        let path = UIBezierPath()
        let pathLayer = CAShapeLayer()

        for (index,pathPoint) in arrPathPoints.enumerated() 
            switch index 
            case 0:
                path.move(to: pathPoint)

            case arrPathPoints.count - 1:
                path.addLine(to: pathPoint)
                path.close()

            default:
                path.addLine(to: pathPoint)
            
        

        pathLayer.path = path.cgPath
        pathLayer.strokeColor = lineColor.cgColor
        pathLayer.lineWidth = lineWidth
        pathLayer.fillColor = self.color

        return pathLayer
    

类我的控制器

extension FirstView: TriangleViewProtocol 
    func shapeTapped() 
      // Action on blue side
    
    func outShapeTapped(touch: UITouch) 
      //send outside actions to bellow view
        guard let filteredView = self.view.subviews.filter( type(of: $0) != TriangleView.self && type(of: $0) == UIStackView.self ).first,
            let view = filteredView.hitTest(touch.location(in: filteredView), with: nil),
            let button = view as? UIButton else  return 
        button.sendActions(for: .touchUpInside)
    


我的 .xib: 现在其他子视图(在我的情况下是 stackView)在三角形被点击时接收点击。

【讨论】:

以上是关于如何创建对角线切割视图以在配置文件屏幕中使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中创建共享导航栏以在多个视图之间进行交互? [关闭]

如何配置 tfs build 以在发布构建完成时复制 dll

如何从我的 webpack 2 配置中创建/生成/导出文件以在我的 React 代码中使用?

如何创建对角分割且两半可点击的布局?

如何配置maven以在不同环境中使用不同的log4j.properties文件

Logrotate切割日志