Как создать в Swift круглое профильное изображение или закругленное Угловое Изображение с границей, которая не протекает?
на основе исходный код ниже:
@IBOutlet var myUIImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.makingRoundedImageProfileWithRoundedBorder()
}
private func makingRoundedImageProfileWithRoundedBorder() {
// Making a circular image profile.
// self.myUIImageView.layer.cornerRadius = self.myUIImageView.frame.size.width / 2
// Making a rounded image profile.
self.myUIImageView.layer.cornerRadius = 20.0
self.myUIImageView.clipsToBounds = true
// Adding a border to the image profile
self.myUIImageView.layer.borderWidth = 10.0
self.myUIImageView.layer.borderColor = UIColor.whiteColor().CGColor
}
действительно, я могу отобразить круговой или округленный UIImageView, но проблема в том, что если мы добавим границу, изображение немного утечет. Это намного хуже с круговым UIImageView, он протекает всякий раз, когда граница согнута, поэтому протекает везде! Вы можете найти скриншот результата ниже:
любой способ исправить это в Swift? Любой пример кода, который отвечает на этот вопрос, будет высоко оценить.
Примечание: насколько это возможно, решение должно быть совместимо с iOS 7 и 8+.
3 ответов
Первый Вариант
основываясь на предложении @Jesper Schläger
"если я могу предложить быстрое и грязное решение:
вместо добавления границы в представление изображения, вы можете просто добавить еще один белый вид под видом изображения. Сделайте вид расширенным на 10 точек в любом направлении и дайте ему радиус угла 20.0. Дайте виду изображения радиус угла 10.0."
вы можете найти Свифт реализация ниже:
import UIKit
class ViewController: UIViewController {
@IBOutlet var myUIImageView: UIImageView!
@IBOutlet var myUIViewBackground: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Making a circular UIView: cornerRadius = self.myUIImageView.frame.size.width / 2
// Making a rounded UIView: cornerRadius = 10.0
self.roundingUIView(self.myUIImageView, cornerRadiusParam: 10)
self.roundingUIView(self.myUIViewBackground, cornerRadiusParam: 20)
}
private func roundingUIView(let aView: UIView!, let cornerRadiusParam: CGFloat!) {
aView.clipsToBounds = true
aView.layer.cornerRadius = cornerRadiusParam
}
}
Второй Вариант
было бы установить маску круга над CALayer.
вы можете найти С реализация этого второго решения ниже:
CALayer *maskedLayer = [CALayer layer];
[maskedLayer setFrame:CGRectMake(50, 50, 100, 100)];
[maskedLayer setBackgroundColor:[UIColor blackColor].CGColor];
UIBezierPath *maskingPath = [UIBezierPath bezierPath];
[maskingPath addArcWithCenter:maskedLayer.position
radius:40
startAngle:0
endAngle:360
clockwise:TRUE];
CAShapeLayer *maskingLayer = [CAShapeLayer layer];
[maskingLayer setPath:maskingPath.CGPath];
[maskedLayer setMask:maskingLayer];
[self.view.layer addSublayer:maskedLayer];
если вы прокомментируете из строки UIBezierPath *maskingPath = [UIBezierPath bezierPath];
через [maskedLayer setMask:maskingLayer];
вы увидите, что слой представляет собой квадрат. Однако, когда эти линии не комментируются, слой представляет собой круг.
примечание: Я не тестировал это второе решение не обеспечило быструю реализацию, поэтому не стесняйтесь тестировать его и дайте мне знать, работает ли он или нет через раздел комментариев ниже. Также не стесняйтесь редактировать этот пост, добавляя быструю реализацию этого второго решения.
Если я могу предложить быстрое и грязное решение:
вместо добавления границы в представление изображения, вы можете просто добавить еще один белый вид под видом изображения. Сделайте вид расширенным на 10 точек в любом направлении и дайте ему радиус угла 20.0. Дайте виду изображения радиус угла 10.0.
Я работал над улучшением кода, но он продолжает сбой. Я буду работать над этим, но у меня, похоже, есть (грубая) версия:
редактировать обновлено с немного более приятной версией. Мне не нравится init:coder
метод, но, возможно, это может быть учтено/улучшено
class RoundedImageView: UIView {
var image: UIImage? {
didSet {
if let image = image {
self.frame = CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
}
}
}
var cornerRadius: CGFloat?
private class func frameForImage(image: UIImage) -> CGRect {
return CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
}
override func drawRect(rect: CGRect) {
if let image = self.image {
image.drawInRect(rect)
let cornerRadius = self.cornerRadius ?? rect.size.width/10
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
UIColor.whiteColor().setStroke()
path.lineWidth = cornerRadius
path.stroke()
}
}
}
let image = UIImage(named: "big-teddy-bear.jpg")
let imageView = RoundedImageView()
imageView.image = image
Дайте мне знать, если это то, что вы ищете.
небольшое пояснение:
как я уверен, вы нашли, "граница", которую iOS может применить, не является замечательно, и показывает углы по какой-то причине. Я нашел несколько других решений, но ни одно из них не сработало. Причина в том, что это подкласс UIView
, а не UIImageView
, это drawRect:
не вызывается для подклассов UIImageView
. Я не уверен в производительности этого кода, но он кажется хорошим от моего (ограниченного) тестирования
исходный код:
class RoundedImageView: UIView {
var image: UIImage? {
didSet {
if let image = image {
self.frame = CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
}
}
}
private class func frameForImage(image: UIImage) -> CGRect {
return CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
}
override func drawRect(rect: CGRect) {
if let image = self.image {
self.image?.drawInRect(rect)
let path = UIBezierPath(roundedRect: rect, cornerRadius: 50)
UIColor.whiteColor().setStroke()
path.lineWidth = 10
path.stroke()
}
}
}
let image = UIImage(named: "big-teddy-bear.jpg")
let imageView = RoundedImageView()
imageView.image = image
imageView.layer.cornerRadius = 50
imageView.clipsToBounds = true