2016-11-07 2 views
2

Я пытаюсь сделать UIView, чтобы показать нижний край зигзагообразного края. Что-то вроде http://www.shutterstock.com/pic-373176370/stock-vector-receipt-vector-icon-invoice-flat-illustration-cheque-shadow-bill-with-total-cost-amount-and-dollar-symbol-abstract-text-receipt-paper-isolated-on-green.html?src=zMGBKj_5etMCcRB3cKmCoA-1-2CAShaperLayer as mask показать только 1/4 UIView

У меня есть метод, который создает путь и устанавливается как маска, но он отображается как 1/4 вида. Нужно ли мне устанавливать что-то еще? Похоже на проблему сетчатки или проблему с координатами, но не знаете, какой из них.

func layoutZigZag(bounds: CGRect) -> CALayer { 
    let maskLayer = CAShapeLayer() 
    maskLayer.bounds = bounds 
    let path = UIBezierPath() 

    let width = bounds.size.width 
    let height = bounds.size.height 

    let topRight = CGPoint(x: width , y: height) 
    let topLeft = CGPoint(x: 0 , y: height) 
    let bottomRight = CGPoint(x: width , y: 0) 
    let bottomLeft = CGPoint(x: 0 , y: 0) 

    let zigzagHeight: CGFloat = 10 
    let numberOfZigZag = Int(floor(width/23.0)) 
    let zigzagWidth = width/CGFloat(numberOfZigZag) 

    path.move(to: topLeft) 
    path.addLine(to: bottomLeft) 

    // zigzag 
    var currentX = bottomLeft.x 
    var currentY = bottomLeft.y 
    for i in 0..<numberOfZigZag { 
     let upper = CGPoint(x: currentX + zigzagWidth/2, y: currentY + zigzagHeight) 
     let lower = CGPoint(x: currentX + zigzagWidth, y: currentY) 

     path.addLine(to: upper) 
     path.addLine(to: lower) 

     currentX += zigzagWidth 
    } 

    path.addLine(to: topRight) 
    path.close() 

    maskLayer.path = path.cgPath 
    return maskLayer 
} 

and 

let rect = CGRect(x: 0, y: 0, width: 320, height: 400) 
let view = UIView(frame: rect) 
view.backgroundColor = UIColor.red 
let zigzag = layoutZigZag(bounds: rect) 
view.layer.mask = zigzag 

Путь выглядеть правильно

Path look correct

Результат 1/4 зрения

Result

+0

Проверьте 'contentScale' если ваш слой (после того, как он был назначен вид). Возможно, он неправильно настроен на 2.0 для дисплеев сетчатки. Если это так, координата слоя будет интерпретироваться как физические пиксели вместо логических точек. – Codo

ответ

1

Изменение maskLayer.bounds = bounds к maskLayer.frame = bounds

Update:

Перевернутый из-за разницы между UI и CG, мы создаем путь в UIBezierPath и преобразования этого пути в качестве CGPath (maskLayer.path = path.cgPath). Сначала мы должны знать разницу, где CGPath is Quartz 2D и происхождение находится в левом нижнем углу, тогда как в UIBezierPath is UIKitпроисхождение находится в верхнем левом углу. В соответствии с вашим кодом применяемые координаты соответствуют верхнему левому, т.е. UIBezierPath, когда мы преобразуемся в CGPath (происхождение внизу слева), оно перевернуто. поэтому измените код, как показано ниже, чтобы получить желаемый эффект.

let topRight = CGPoint(x: width , y: 0) 
    let topLeft = CGPoint(x: 0 , y: 0) 
    let bottomLeft = CGPoint(x: 0 , y: (height - zigzagHeight)) 

Quartz 2D системы координат

enter image description here

UIBezierPath системы координат

enter image description here

+0

Это работает спасибо! Не могли бы вы немного объяснить проблему? Я предполагаю, что кадр равен нулю, так как я его не задавал, но почему он так выглядит как прямоугольник 1/4. – sarunw

+0

И результат будет по-прежнему вверх дном (путь выглядит правильно), но при применении маски он переворачивается вверх ногами. Это нормально? Каков правильный способ справиться с этим? – sarunw

+0

@sarunw Пожалуйста, проверьте обновленный ответ и проверьте это так, чтобы узнать о различии между фреймом и границами. http://stackoverflow.com/questions/1210047/cocoa-whats-the-difference-between-the-frame-and-the-bounds – Jeyamahesan