Это не было давно, что я даже не знал, как объявить, что BГ©zier, уже не говоря о знают, как использовать пути BГ©zier для создания пользовательской формы. Следующее - то, что я изучил. Оказывается, что они не так страшны, как они кажутся сначала.
, Это основные шаги:
drawRect
или использование CAShapeLayer
. Вы могли сделать что-либо, но как пример я выбрал форму ниже. Это могло быть всплывающее окно, включают клавиатуру.
, Взгляд назад на Вашу форму разрабатывает и разламывает его на более простые элементы строк (для прямых линий), дуги (для кругов и круглых углов), и кривые (для чего-либо еще).
Вот то, на что был бы похож наш дизайн в качестве примера:
, Мы произвольно запустим в левом нижнем угле и работе по часовой стрелке. Я буду использовать сетку в изображении для получения значений X и Y для точек. Я буду hardcode все здесь, но конечно Вы не сделали бы этого в реальном проекте.
базовый процесс:
UIBezierPath
moveToPoint
addLineToPoint
addArcWithCenter
addCurveToPoint
Вот код для создания пути в изображении выше.
func createBezierPath() -> UIBezierPath {
// create a new path
let path = UIBezierPath()
// starting point for the path (bottom left)
path.move(to: CGPoint(x: 2, y: 26))
// *********************
// ***** Left side *****
// *********************
// segment 1: line
path.addLine(to: CGPoint(x: 2, y: 15))
// segment 2: curve
path.addCurve(to: CGPoint(x: 0, y: 12), // ending point
controlPoint1: CGPoint(x: 2, y: 14),
controlPoint2: CGPoint(x: 0, y: 14))
// segment 3: line
path.addLine(to: CGPoint(x: 0, y: 2))
// *********************
// ****** Top side *****
// *********************
// segment 4: arc
path.addArc(withCenter: CGPoint(x: 2, y: 2), // center point of circle
radius: 2, // this will make it meet our path line
startAngle: CGFloat(M_PI), // π radians = 180 degrees = straight left
endAngle: CGFloat(3*M_PI_2), // 3π/2 radians = 270 degrees = straight up
clockwise: true) // startAngle to endAngle goes in a clockwise direction
// segment 5: line
path.addLine(to: CGPoint(x: 8, y: 0))
// segment 6: arc
path.addArc(withCenter: CGPoint(x: 8, y: 2),
radius: 2,
startAngle: CGFloat(3*M_PI_2), // straight up
endAngle: CGFloat(0), // 0 radians = straight right
clockwise: true)
// *********************
// ***** Right side ****
// *********************
// segment 7: line
path.addLine(to: CGPoint(x: 10, y: 12))
// segment 8: curve
path.addCurve(to: CGPoint(x: 8, y: 15), // ending point
controlPoint1: CGPoint(x: 10, y: 14),
controlPoint2: CGPoint(x: 8, y: 14))
// segment 9: line
path.addLine(to: CGPoint(x: 8, y: 26))
// *********************
// **** Bottom side ****
// *********************
// segment 10: line
path.close() // draws the final line to close the path
return path
}
Примечание: Часть вышеупомянутого кода может быть уменьшена путем добавления строки и дуги в единственной команде (так как дуга имеет подразумеваемую начальную точку). См. здесь для получения дополнительной информации.
, Мы можем потянуть путь или в слое или в [1 113].
Метод 1: Потяните путь в уровне
, Наш пользовательский класс похож на это. Мы добавляем наш путь Bezier к новому CAShapeLayer
, когда представление инициализируется.
import UIKit
class MyCustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
// Create a CAShapeLayer
let shapeLayer = CAShapeLayer()
// The Bezier path that we made needs to be converted to
// a CGPath before it can be used on a layer.
shapeLayer.path = createBezierPath().cgPath
// apply other properties related to the path
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.lineWidth = 1.0
shapeLayer.position = CGPoint(x: 10, y: 10)
// add the new layer to our custom view
self.layer.addSublayer(shapeLayer)
}
func createBezierPath() -> UIBezierPath {
// see previous code for creating the Bezier path
}
}
И создание нашего представления в Контроллере Представления как это
override func viewDidLoad() {
super.viewDidLoad()
// create a new UIView and add it to the view controller
let myView = MyCustomView()
myView.frame = CGRect(x: 100, y: 100, width: 50, height: 50)
myView.backgroundColor = UIColor.yellow
view.addSubview(myView)
}
Мы добираемся...
Хм, это является немного маленьким потому что я hardcoded все числа в. Я могу увеличить масштаб размера пути, тем не менее, как это:
let path = createBezierPath()
let scale = CGAffineTransform(scaleX: 2, y: 2)
path.apply(scale)
shapeLayer.path = path.cgPath
Метод 2: Потяните путь в [1 115]
Используя [1 116], медленнее, чем рисование к слою, таким образом, это не рекомендуемый метод, если Вам не нужен он.
Вот пересмотренный код для нашего пользовательского представления:
import UIKit
class MyCustomView: UIView {
override func draw(_ rect: CGRect) {
// create path (see previous code)
let path = createBezierPath()
// fill
let fillColor = UIColor.white
fillColor.setFill()
// stroke
path.lineWidth = 1.0
let strokeColor = UIColor.blue
strokeColor.setStroke()
// Move the path to a new location
path.apply(CGAffineTransform(translationX: 10, y: 10))
// fill and stroke the path (always do these last)
path.fill()
path.stroke()
}
func createBezierPath() -> UIBezierPath {
// see previous code for creating the Bezier path
}
}
, который дает нам тот же результат...
я действительно рекомендую смотреть на следующие материалы. Они - то, что наконец сделало пути BГ©zier понятными для меня. (И учил меня, как объявить его:/Л€bЙ› zi eЙЄ/.)
Было бы легче, если Вы будете использовать CAShapeLayer
, как это:
CAShapeLayer *shapeView = [[CAShapeLayer alloc] init];
И набор path
:
[shapeView setPath:[self createPath].CGPath];
Наконец добавляют его:
[[self.view layer] addSublayer:shapeView];
Можно использовать CAShapeLayer
, чтобы сделать это.
Как это...
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [self createPath].CGPath;
shapeLayer.strokeColor = [UIColor redColor].CGColor; //etc...
shapeLayer.lineWidth = 2.0; //etc...
shapeLayer.position = CGPointMake(100, 100); //etc...
[self.layer addSublayer:shapeLayer];
Это затем добавит и потянет путь, не имея необходимость переопределять drawRect
.
Существует несколько способов выполнить то, чего Вы желаете. Те, которых я видел больше всего: переопределите drawRect, вовлеките Вашу форму в CAShapeLayer и затем добавьте его, поскольку подуровень к Вашему представлению, или тянут Ваш путь на другой контекст , сохраняют это как изображение и затем добавляют его к Вашему представлению.
Все они являются разумным выбором, и какой является лучшим, зависит от многих других факторов тех, которые являются Вами собирающийся постоянно добавлять формы, как часто это называют, и т.д.
Как другие плакаты, на которые указывают, с помощью слоя фигуры, хороший способ пойти.
Слои фигуры, вероятно, чтобы дать Вам лучшую производительность, чем переопределение drawRect.
, Если Вы хотите потянуть свой путь сами затем да, необходимо переопределить drawRect для пользовательского класса представления.
Да, необходимо переопределить drawrect, если Вы хотите потянуть что-нибудь. Создание UIBezierPath может быть сделано где угодно, Но потянуть что-то необходимо сделать это в drawrect
метод
, необходимо звонить setNeedsDisplay
при переопределении drawRect в подклассе UIView, который является в основном пользовательским представлением, тянущим что-то на экране, как строки, изображение, прямоугольник.