Я хотел бы создать UIView с закругленным верхним краем как это изображение, как я могу это сделать?Создать UIView с закругленным верхним краем
Wanted результат
Не хотел результат
Я хотел бы создать UIView с закругленным верхним краем как это изображение, как я могу это сделать?Создать UIView с закругленным верхним краем
Wanted результат
Не хотел результат
Чтобы перепечатывать ответ я отправил в другом потоке:
теперь я могу подтвердить, что это ошибка введена после того, как прошивка 6. У меня есть старый 4s под управлением IOS 6.1. На этой машине этот код:
path = [UIBezierPath bezierPathWithRoundedRect: bounds
byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii: CGSizeMake(bounds.size.width/2, bounds.size.width/6)
];
Создает закругленный прямоугольник с углами овальной формы. Кривая намного более постепенными на верхней части кривой, и гораздо острее по бокам, как и следовало ожидать:
Это IOS 6,1 изображения, с углами, так как они должны быть:
а вот то, что тот же код выглядит как при запуске с прошивки 8.1.2:
оказывается, что на прошивке> = 7.0, она игнорирует высоту заданного радиуса и использует значение ширины и для высоты и ширину угловых овалов, которая заставляет их всегда быть четвертными кругами.
Я зарегистрировал ошибку в системе репортера ошибок яблока. Посмотрим, что они скажут. Я предлагаю всем, кто видит эту проблему, сообщать об ошибке. Чем больше отчетов они получат, тем больше вероятность их исправить.
(игнорировать UISwitch на дне, что осталось от предыдущего теста.).
Edit: Я написал код, который строит кривую Безье, что примерно приближается внешний вид кривой, порожденной прошивкой < 7 Я только что нашел article on approximating circles with bezier curves. Используя контрольные точки из этой статьи, было бы не так сложно создать собственный эквивалент метода bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
, который работает во всех версиях iOS.
После того, как я нашел где-то в SO. Он отлично работает. Вот код:
-(UIView *)roundCornersOnView:(UIView *)view onTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius {
if (tl || tr || bl || br) {
UIRectCorner corner = (bl ? UIRectCornerBottomLeft : 0) | (br ? UIRectCornerBottomRight : 0) | (tl ? UIRectCornerTopLeft : 0) | (tr ? UIRectCornerTopRight : 0);
UIView *roundedView = view;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:roundedView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = roundedView.bounds;
maskLayer.path = maskPath.CGPath;
roundedView.layer.mask = maskLayer;
return roundedView;
} else {
return view;
}
}
Пусть ваш View имя _tView, то звоните:
_tView = (UIView *)[self roundCornersOnView:_tView onTopLeft:YES topRight:YES bottomLeft:NO bottomRight:NO radius:25.0];
Это даст выход так:
Почему бы просто не взять «UIRectCorner» как одно поле битмаски - кажется странным, расширяя список аргументов, а затем просто сворачивая его обратно в правильную форму. –
@ Paul.s> Спасибо за указание. Под редакцией! :) – Rashad
@ Rashad: Я уже нашел несколько решений вокруг закругленных углов, но чтобы иметь результат, как и у моей фотографии, край должен быть изогнутым, а не cornes. – Kenzo
Там также простой способ сделать это в раскадровки.
Правильный способ сделать это (или один из правильных способов) использовать UIBezierCurve
's addQuadCurveToPoint:controlPoint
. Вы можете нарисовать квадратичную кривую от того места, где путь к точке, используя другую точку в качестве контрольной точки, которая является способом определения того, сколько дуги и кривой получится в результате пути. Однако не забывайте, что если вы используете слой в качестве маски, вам также нужно нарисовать прямоугольную часть фигуры, иначе маска будет просто кривой.
Это правильный ответ. Угловые радиусы не достигнут предполагаемого результата. –
This answer действительно помогли мне я добиться этого эффекта с помощью этого фрагмента кода:
Swift 3,1
extension UIView {
func addBottomRoundedEdge(desiredCurve: CGFloat?) {
let offset: CGFloat = self.frame.width/desiredCurve!
let bounds: CGRect = self.bounds
let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y + bounds.size.height/2, width: bounds.size.width, height: bounds.size.height/2)
let rectPath: UIBezierPath = UIBezierPath(rect: rectBounds)
let ovalBounds: CGRect = CGRect(x: bounds.origin.x - offset/2, y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
rectPath.append(ovalPath)
// Create the shape layer and set its path
let maskLayer: CAShapeLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.path = rectPath.cgPath
// Set the newly created shape layer as the mask for the view's layer
self.layer.mask = maskLayer
}
}
Вы не смогли найти ничего об этом уже на переполнение стека ? В самом деле? _Really? _ – matt
Я уже пробовал это, но это не дает результат, как я хочу: UIBezierPath * maskPath = [UIBezierPath bezierPathWithRoundedRect: rect byRoundingCorners: углы cornerRadii: CGSizeMake (радиус, радиус)]; – Kenzo
@matt Если вы нашли ответ в другом месте, пожалуйста, покажите ссылку так! – Kenzo