ให้มุมโค้งมน UIV


577

มุมมองเข้าสู่ระบบของฉันมีมุมมองย่อยซึ่งมีUIActivityViewและUILabelคำว่า "ลงชื่อเข้าใช้ ... " มุมมองย่อยนี้มีมุมที่ไม่ถูกปัดเศษ ฉันจะทำให้พวกเขารอบได้อย่างไร

มีวิธีใดบ้างที่จะทำได้ภายใน xib ของฉัน?


6
การทำสิ่งนี้ใน IB จะต้องมีการแสดงภาพล่วงหน้าด้วยมุมมน
Ed Marty

9
ไม่จำเป็นต้อง @ ed-marty คำตอบนี้จาก @Gujamin สมควรได้รับเครดิตเพิ่มเนื่องจากแสดงวิธีการใช้cornerRadiusคุณสมบัติกับตารางโดยใช้ตัวสร้างส่วนต่อประสานเท่านั้นโดยไม่ต้องใช้รูปภาพที่แสดงล่วงหน้าหรือตั้งค่าในรหัส
djskinner

1
จาก
@SP

คำตอบ:


1219

ลองสิ่งนี้

#import <QuartzCore/QuartzCore.h> // not necessary for 10 years now  :)

...

view.layer.cornerRadius = 5;
view.layer.masksToBounds = true;

หมายเหตุ: หากคุณพยายามที่จะใช้มุมโค้งมนกับUIViewControllerมุมมองของมันก็ไม่ควรนำไปใช้ในตัวสร้างมุมมองของตัวควบคุม แต่ใน-viewDidLoadหลังจากที่viewมีการยกตัวอย่างจริง


6
โปรดทราบว่าคุณสมบัตินี้มีอยู่ใน iPhone 3.0 ไม่ใช่รุ่นก่อนหน้าเท่านั้น
Kendall Helmstetter Gelner

5
ฉันต้องบอกว่านี่เป็นหนึ่งในคำตอบที่น่าพึงพอใจที่สุดที่ฉันเคยเห็นใน SO การตรวจสอบที่นี่ก่อนช่วยให้ฉันประหยัดเวลาหนึ่งชั่วโมงในการต่อสู้ด้วยเครื่องมือแก้ไขภาพและทำให้ฉันมีความเปราะบางต่อการเปลี่ยนแปลงสี / การปรับขนาด ขอบคุณ!
Justin Searls

20
หมายเหตุที่เกี่ยวข้อง: ทุกคนที่สนใจสารพัดภาพ (เช่นเงา) เพื่อนำไปใช้กับ UIView ได้ง่ายควรตรวจสอบข้อมูลอ้างอิงระดับ CALayer ส่วนใหญ่เป็นเรื่องง่ายเหมือนการตั้งค่าคุณสมบัติหนึ่งหรือสองอย่างเช่นคำตอบด้านบน: developer.apple.com/mac/library/documentation/GraphicsImaging/…
Justin Searls

6
@Ben Collins (หรือใครก็ตามที่มีปัญหานี้) ตรวจสอบให้แน่ใจว่ามุมมองของคุณมีชุด "คลิปย่อย" คุณสามารถตรวจสอบสิ่งนี้ได้ในเครื่องมือสร้างอินเตอร์เฟส
zem

2
มันใช้งานได้ดี แต่ถ้าคุณมีมุมโค้งมนจำนวนมากในมุมมองเลื่อนหรือภาพเคลื่อนไหวใด ๆ (ฉันลองใช้พวกมันใน UITableView) ประสิทธิภาพของคุณจะแย่ลงอย่างมาก มุมมองตารางการเลื่อนที่ราบรื่นดีกลายเป็นสิ่งที่ขาดหายไปอย่างรวดเร็ว: (
Slee

261

คุณยังสามารถใช้คุณลักษณะกำหนดคุณสมบัติผู้ใช้รันไทม์ของตัวสร้างส่วนต่อประสานเพื่อตั้งค่าเส้นทางหลักlayer.cornerRadiusให้เป็นค่า ตรวจสอบให้แน่ใจว่าคุณรวมQuartzCoreไลบรารีไว้ด้วย

เคล็ดลับนี้ยังสามารถใช้ได้กับการตั้งค่า layer.borderWidth แต่มันจะไม่ทำงานlayer.borderColorเช่นนี้คาดว่าจะCGColorไม่ได้เป็นUIColorไม่ได้เป็น

คุณจะไม่สามารถเห็นเอฟเฟกต์ในกระดานเรื่องราวได้เนื่องจากพารามิเตอร์เหล่านี้ได้รับการประเมินที่รันไทม์

การใช้ตัวสร้างส่วนต่อประสานเพื่อตั้งค่ารัศมีมุม


10
อย่าลืมตรวจสอบClip Subviewsตัวเลือกในการดู IB ด้วยเช่นกัน
Peter

2
(หรือ) เพิ่มเส้นทางที่สำคัญ: layer.masksToBounds, ประเภท: บูลีน: ตรวจสอบแล้ว
Amitabh

64

ตอนนี้คุณสามารถใช้หมวดหมู่ swift ใน UIView (รหัสตะโกนรูปภาพ) ด้วย @IBInspectable เพื่อแสดงผลลัพธ์ที่กระดานเรื่องราว (หากคุณกำลังใช้หมวดหมู่ให้ใช้ cornerRadius เท่านั้นและไม่ใช่ layer.cornerRadius เป็นเส้นทางหลัก

extension UIView {
    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }
}

ป้อนคำอธิบายรูปภาพที่นี่


และถ้าคุณใช้คลาสย่อยที่กำหนดเองตรวจสอบให้แน่ใจว่าได้ติดแท็กด้วย@IBDesignableเพื่อรับชมตัวอย่างสดใน IB! (เพิ่มเติมได้ที่nshipster.com/ibinspectable-ibdesignable )
clozach

56

รวดเร็ว

คำตอบสั้น ๆ :

myView.layer.cornerRadius = 8
myView.layer.masksToBounds = true  // optional

คำตอบเพิ่มเติม

หากคุณมาที่คำตอบนี้คุณอาจเห็นพอที่จะแก้ปัญหาของคุณแล้ว ฉันกำลังเพิ่มคำตอบนี้เพื่อให้คำอธิบายที่ชัดเจนยิ่งขึ้นว่าทำไมสิ่งที่พวกเขาทำ

หากคุณเริ่มต้นด้วยปกติUIViewมันมีมุมสี่เหลี่ยม

let blueView = UIView()
blueView.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
blueView.backgroundColor = UIColor.blueColor()
view.addSubview(blueView)

ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถให้มุมรอบโดยการเปลี่ยนคุณสมบัติของมุมมองcornerRadiuslayer

blueView.layer.cornerRadius = 8

ป้อนคำอธิบายรูปภาพที่นี่

ค่ารัศมีที่มากขึ้นจะทำให้มุมมนยิ่งขึ้น

blueView.layer.cornerRadius = 25

ป้อนคำอธิบายรูปภาพที่นี่

และค่าที่น้อยลงจะทำให้มุมมนน้อยลง

blueView.layer.cornerRadius = 3

ป้อนคำอธิบายรูปภาพที่นี่

นี่อาจเพียงพอที่จะแก้ปัญหาของคุณที่นั่น อย่างไรก็ตามบางครั้งมุมมองสามารถมีมุมมองย่อยหรือ sublayer ที่อยู่นอกขอบเขตของมุมมอง ตัวอย่างเช่นถ้าฉันจะเพิ่มมุมมองย่อยเช่นนี้

let mySubView = UIView()
mySubView.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
mySubView.backgroundColor = UIColor.redColor()
blueView.addSubview(mySubView)

หรือถ้าฉันจะเพิ่มเลเยอร์ย่อยแบบนี้

let mySubLayer = CALayer()
mySubLayer.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
mySubLayer.backgroundColor = UIColor.redColor().CGColor
blueView.layer.addSublayer(mySubLayer)

จากนั้นฉันก็จะจบลงด้วย

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้ถ้าฉันไม่ต้องการให้สิ่งต่าง ๆ ห้อยอยู่นอกขอบเขตฉันสามารถทำได้

blueView.clipsToBounds = true

หรือสิ่งนี้

blueView.layer.masksToBounds = true

ซึ่งให้ผลลัพธ์นี้:

ป้อนคำอธิบายรูปภาพที่นี่

ทั้งสองclipsToBoundsและmasksToBoundsมีเทียบเท่า มันเป็นเพียงแค่ว่าคนแรกที่จะใช้กับและครั้งที่สองจะใช้กับUIViewCALayer

ดูสิ่งนี้ด้วย


4
ฉันต้องการเพิ่มการตั้งค่ารัศมีของมุมลงครึ่งหนึ่งของด้านที่สั้นกว่า (ในกรณีนี้blueView.frame.size.height/2) ให้ผลลัพธ์ในมุมที่โค้งมนอย่างสมบูรณ์
Johann Burgess

44

แนวทางที่แตกต่างจากที่ Ed Marty ทำ:

#import <QuartzCore/QuartzCore.h>

[v.layer setCornerRadius:25.0f];
[v.layer setMasksToBounds:YES];

คุณต้องการ setMasksToBounds เพื่อให้โหลดวัตถุทั้งหมดจาก IB ... ฉันมีปัญหาเมื่อมุมมองของฉันถูกปัดเศษ แต่ไม่มีวัตถุจาก IB: /

สิ่งนี้แก้ไขได้ = D หวังว่าจะช่วยได้!


48
แตกต่างกันอย่างไร นอกเหนือจากการไม่ใช้ไวยากรณ์จุด?
user102008

3
[v.layer setMasksToBounds: YES]; \ n บรรทัดนี้เป็นเวทย์มนตร์มันแก้ปัญหาใหญ่ของฉัน
Cullen SUN

3
ฉันเขียนสิ่งนี้เมื่อฉันเริ่มพัฒนา iOS และไม่ทราบว่าไม่มีความแตกต่างระหว่างจุดไวยากรณ์และไวยากรณ์ของวงเล็บ ดังนั้นฉันจึงเขียนว่า "แตกต่าง" รหัสของฉันยังรวมการนำเข้า <> ที่ Ed Marty ไม่ได้มีในการตอบกลับดั้งเดิมของเขา (แก้ไขในภายหลัง) และดังนั้นคำตอบของฉันช่วยให้ผู้คนแก้ไขปัญหาของพวกเขาได้
Kristian Flatheim Jensen

28

ตามที่อธิบายไว้ในโพสต์บล็อกนี่คือวิธีการปัดเศษมุมของ UIView:

+(void)roundView:(UIView *)view onCorner:(UIRectCorner)rectCorner radius:(float)radius
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds
                                                   byRoundingCorners:rectCorner
                                                         cornerRadii:CGSizeMake(radius, radius)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view.bounds;
    maskLayer.path = maskPath.CGPath;
    [view.layer setMask:maskLayer];
    [maskLayer release];
}

ส่วนที่น่าสนใจเกี่ยวกับมันคือคุณสามารถเลือกมุมที่คุณต้องการปัดขึ้น


6
แทนที่จะให้ลิงก์ไปยังเว็บไซต์ภายนอกเราต้องการให้คำตอบมีอยู่ในตัวเองดังนั้นฉันจึงนำรหัสที่เกี่ยวข้องจากบล็อกโพสต์ที่ลิงก์ไว้ในคำตอบของคุณ ผู้คนสามารถไปที่โพสต์บล็อกเพื่อดูรายละเอียดเพิ่มเติม แต่ต้องแน่ใจว่าเนื้อหาจะอยู่รอดหากโพสต์ที่มีปัญหานั้นหายไป นอกจากนี้คุณโพสต์คำตอบนี้ไปยังคำถามต่าง ๆ ที่ไม่ได้ถามในสิ่งเดียวกัน คำถามเหล่านั้นถูกนำออกและคำถามหนึ่งคำถามถูกปิดเป็นซ้ำกับคำถามนี้ เราชอบที่จะมีคำตอบที่สร้างขึ้นเพื่อให้ตรงกับคำถามแต่ละข้อ
Brad Larson

5
ทิพยเนตร โพสต์บล็อกคือ 404 ในขณะนี้
Anthony C

วิธีนี้สะอาด แต่จะซ่อนเอฟเฟกต์เงาใด ๆ ในมุมมอง
thesummersign

19

คุณต้องนำเข้าไฟล์ส่วนหัวก่อน <QuartzCore/QuartzCore.h>

 #import QuartzCore/QuartzCore.h>

[yourView.layer setCornerRadius:8.0f];
yourView.layer.borderColor = [UIColor redColor].CGColor;
yourView.layer.borderWidth = 2.0f;
[yourView.layer setMasksToBounds:YES];

อย่าพลาดที่จะใช้ - setMasksToBoundsไม่เช่นนั้นอาจไม่แสดงผล


2
ไม่จำเป็นต้องนำเข้า "QuartzCore / QuartzCore.h"
Sudhir Kumar

ใช่คุณต้องนำเข้า
ลอร์ด Zsolt

3
@LordZsolt บางทีพวกเขาเปลี่ยนมันด้วย iOS7 แต่คุณไม่จำเป็นต้องนำเข้า QuartzCore อีกต่อไป
Marc

14

คุณสามารถใช้UIViewคลาสที่กำหนดเองดังต่อไปนี้ซึ่งสามารถเปลี่ยนสีและความกว้างของเส้นขอบได้ เช่นนี้IBDesignalbeคุณสามารถเปลี่ยนคุณสมบัติในตัวสร้างส่วนต่อประสานได้เช่นกัน

ป้อนคำอธิบายรูปภาพที่นี่

import UIKit

@IBDesignable public class RoundedView: UIView {

    @IBInspectable var borderColor: UIColor = UIColor.white {
        didSet {
            layer.borderColor = borderColor.cgColor
        }
    }

    @IBInspectable var borderWidth: CGFloat = 2.0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat = 0.0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }

}

6
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 50, 200, 200)];

view.layer.backgroundColor = [UIColor whiteColor].CGColor;
view.layer.cornerRadius = 20.0;
view.layer.frame = CGRectInset(v.layer.frame, 20, 20);

view.layer.shadowOffset = CGSizeMake(1, 0);
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .25;

[self.view addSubview:view];
[view release];

การใช้ setMasksToBounds เป็นสิ่งสำคัญ การตั้งค่าสีพื้นหลังและเงาไม่ได้เป็น
djskinner

3

Swift 4 - การใช้ IBDesignable

   @IBDesignable
    class DesignableView: UIView {
    }

    extension UIView
    {

        @IBInspectable
        var cornerRadius: CGFloat {
            get {
                return layer.cornerRadius
            }
            set {
            layer.cornerRadius = newValue
        }
    }
}

ฉันขอโทษ แต่เป็นผู้ใช้ใหม่ในการพัฒนา IOS วิธีแก้ปัญหาป้องกันไม่ให้layer.cornerRadiusกลับสู่สถานะเดิมได้อย่างไร (เช่นกระดานเรื่องราวของ xcode รู้ได้อย่างไรว่าจะตั้งค่าได้อย่างไรcornerRadiusหลังจากUIViewเริ่มใช้งานดั้งเดิมแล้ว)
AlanSTACK


3

- SwiftUI

ใน SwiftUI คุณสามารถใช้cornerRadiusตัวดัดแปลงโดยตรงกับสิ่งที่Viewคุณต้องการ ตัวอย่างของคำถามนี้:

Text("Signing In…")
    .padding(16)
    .background(Color.red)
    .cornerRadius(50)

ดูตัวอย่าง

โปรดทราบว่าไม่มีเพชรเหมือนรัศมีดังนั้นแม้ว่าคุณจะตั้งมุมรัศมีมากกว่าครึ่งหนึ่งของความสูงมันจะกลมอย่างราบรื่น

ชำระเงิน คำตอบนี้เพื่อดูวิธีการปัดเศษมุมเฉพาะใน SwiftUI


2

โปรดนำเข้าQuartzcore frameworkจากนั้นคุณต้องตั้งค่าsetMaskToBoundsเป็นTRUEนี้สายสำคัญมาก

แล้ว: [[yourView layer] setCornerRadius:5.0f];


2
UIView* viewWithRoundedCornersSize(float cornerRadius,UIView * original)
{
    // Create a white border with defined width
    original.layer.borderColor = [UIColor yellowColor].CGColor;
    original.layer.borderWidth = 1.5;

    // Set image corner radius
    original.layer.cornerRadius =cornerRadius;

    // To enable corners to be "clipped"
    [original setClipsToBounds:YES];
    return original;
}

2

ทำสิ่งนี้โดยใช้โปรแกรมใน obj c

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 50,    200, 200)];

view.layer.backgroundColor = [UIColor whiteColor].CGColor;
view.layer.cornerRadius = 20.0;
view.layer.frame = CGRectInset(v.layer.frame, 20, 20);

[view.layer.shadowOffset = CGSizeMake(1, 0);
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .25;][1]

[self.view addSubview:view];

เราสามารถทำสิ่งนี้ได้จากสโตริโอบอร์ด

 layer.cornerRadius  Number  5

ป้อนคำอธิบายรูปภาพที่นี่


2

ถ้ามุมแบบกลมไม่ทำงานในviewDidload ()ควรเขียนโค้ดในviewDidLayoutSubview ()

-(void)viewDidLayoutSubviews
{
    viewTextfield.layer.cornerRadius = 10.0 ;                                               
    viewTextfield.layer.borderWidth = 1.0f;
    viewTextfield.layer.masksToBounds =  YES;
    viewTextfield.layer.shadowRadius = 5;
    viewTextfield.layer.shadowOpacity = 0.3;
    viewTextfield.clipsToBounds = NO;
    viewTextfield.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
}

หวังว่านี่จะช่วยได้!


0

คุณยังสามารถใช้รูปภาพ:

UIImage *maskingImage = [UIImage imageNamed:@"bannerBarBottomMask.png"];
CALayer *maskingLayer = [CALayer layer];
maskingLayer.frame = CGRectMake(-(self.yourView.frame.size.width - self.yourView.frame.size.width) / 2
                                , 0
                                , maskingImage.size.width
                                , maskingImage.size.height);
[maskingLayer setContents:(id)[maskingImage CGImage]];
[self.yourView.layer setMask:maskingLayer];

0

ตั้งค่ามุมทรัพย์สินอันตรายสำหรับการดูแบบรอบ

กำหนด masksToBounds ค่าบูลีนสำหรับรูปภาพจะยังไม่ถูกดึงออกนอกขอบเขตรัศมีมุม

view.layer.cornerRadius = 5;

view.layer.masksToBounds = YES;

0

ใช้ส่วนขยาย UIView:

extension UIView {    

func addRoundedCornerToView(targetView : UIView?)
{
    //UIView Corner Radius
    targetView!.layer.cornerRadius = 5.0;
    targetView!.layer.masksToBounds = true

    //UIView Set up boarder
    targetView!.layer.borderColor = UIColor.yellowColor().CGColor;
    targetView!.layer.borderWidth = 3.0;

    //UIView Drop shadow
    targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
    targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
    targetView!.layer.shadowOpacity = 1.0
}
}

การใช้งาน:

override func viewWillAppear(animated: Bool) {

sampleView.addRoundedCornerToView(statusBarView)

}

0

ใน Swift 4.2 และ Xcode 10.1

let myView = UIView()
myView.frame = CGRect(x: 200, y: 200, width: 200, height: 200)
myView.myViewCorners()
//myView.myViewCorners(width: myView.frame.width)//Pass View width
view.addSubview(myView)

extension UIView {
    //If you want only round corners
    func myViewCorners() {
        layer.cornerRadius = 10
        layer.borderWidth = 1.0
        layer.borderColor = UIColor.red.cgColor
        layer.masksToBounds = true
    }
    //If you want complete round shape, enable above comment line
    func myViewCorners(width:CGFloat) {
        layer.cornerRadius = width/2
        layer.borderWidth = 1.0
        layer.borderColor = UIColor.red.cgColor
        layer.masksToBounds = true
    }
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.