2016-04-04 2 views
1

У меня есть изображение в масках, которое используется UIBezierPath(), и я хотел бы иметь границу вокруг маскированной части, а не оригинальное изображение. Я подошел так близко к моему (бесчисленному количеству) попытке с помощью проб и ошибок и, неустанно, отказался. Любой более простой способ сделать это?Swift - Border Inside Masked Image

Это, как далеко я пришел к своей цели:

enter image description here

Я хотел бы иметь границ заходят внутрь! :-(

Swift 2 Код:

let picture = UIImageView(image: UIImage(named: "myPicture.png")) 
picture.layer.contentMode = .ScaleAspectFit 
picture.layer.clipsToBounds = true 

let maskLayer = CAShapeLayer() 
picture.layer.mask = maskLayer 

maskLayer.frame = CGRect(origin: CGPointZero, size: picture.image.size) 
let radius = picture.size.width/2 
let center = CGPoint(x: picture.size.width/2, y: picture.size.height/2) 

let path = UIBezierPath() 
      path.moveToPoint(center) 
      path.addArcWithCenter(center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI*2.0*0.2), clockwise: true) 

maskLayer.path = path.CGPath 

picture.layer.mask = maskLayer 

picture.layer.borderWidth = 3 
picture.layer.borderColor = UIColor.purpleColor().CGColor 
picture.layer.cornerRadius = picture.layer.bounds.width/2 

ответ

1

Предполагая, что я понимаю, что вы имеете в виду: «Я хотел бы, чтобы граница заходит внутрь» - я бы рекомендовал использовать другой CAShapeLayer для отображения границы как погладил путь, и добавить его в качестве подслоя в слое вашего зрения изображения.

вы просто должны установить ваш пропуск в пути вы определили для вашей маски, установите strokeColor и lineWidth и установите fillColor в clearColor.

Что-то вроде этого следует сделать трюк:

// insert your image here 
guard let img = UIImage(named: "4.png") else { 
    return 
} 

// frame of your image view 
let frame = CGRectInset(view.bounds, 10, 10) 

// your picture view 
let pictureView = UIImageView(image: img) 
pictureView.frame = frame 
pictureView.contentMode = .ScaleAspectFit 
pictureView.clipsToBounds = true 

// the radius and center of your path 
let radius = pictureView.frame.size.width*0.5 
let center = CGPoint(x: pictureView.frame.size.width*0.5, y: pictureView.frame.size.height*0.5) 

// your masking & stroking path 
let path = UIBezierPath() 
path.moveToPoint(center) 
path.addArcWithCenter(center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI*2.0*0.8), clockwise: true) 
path.closePath() 

// the layer used to mask the image view 
let maskLayer = CAShapeLayer() 
maskLayer.frame = pictureView.bounds 
maskLayer.path = path.CGPath 
pictureView.layer.mask = maskLayer 

// the layer used to draw the border 
let strokeLayer = CAShapeLayer() 
strokeLayer.frame = pictureView.bounds 
strokeLayer.fillColor = UIColor.clearColor().CGColor 
strokeLayer.path = path.CGPath 
strokeLayer.strokeColor = UIColor.purpleColor().CGColor 
strokeLayer.lineWidth = 10 
pictureView.layer.addSublayer(strokeLayer) 

view.addSubview(pictureView) 

дает следующий результат:

enter image description here

Кроме того, я хотел бы отметить, что код содержится в OP даже не компилировались - пожалуйста, всегда копируйте и вставляйте свой код из IDE вместо того, чтобы пытаться ввести его сами!

+0

Вы серьезно спасатель! Ваше решение было действительно близко к моей последней попытке, прежде чем я увидел ваше сообщение, и я не знал, почему он не работал, пока я не понял, что в моем другом вопросе «path.closePath()» отсутствовал из вашего невероятного класса MaskedImageView. Теперь я вижу его значение. Спасибо огромное! – theflarenet

+1

@theflarenet ah yes, в то время как 'CAShapeLayer' способен вычислять область заполнения без' path.closePath() '- ему нужно полностью погладить путь. Ради завершения я уточню свой другой ответ (хотя в этом случае это не имеет значения). Рад помочь как всегда :) – Hamish