Ustawienie promienia narożnika w UIImageView nie działa

133

Jestem trochę zagubiony. Użyłem właściwości warstwy UIView do zaokrąglenia rogów wielu elementów w mojej aplikacji. Jednak ten jeden UIImageView po prostu nie jest zgodny. Nie wiem, czego mi brakuje.

UIImageView (o nazwie previewImage) znajduje się w komórce widoku tabeli. Próbowałem ustawić wiele lokalizacji właściwości cornerRadius (w samej komórce i kontrolerze, który tworzy komórkę) bez skutku.

static NSString *CellIdentifier = @"MyTableViewCell";

MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
    cell = [topLevelObjects objectAtIndex:0];
    cell.previewImage.layer.cornerRadius = 20; //Made it 20 to make sure it's obvious.
}

Czy jest coś, czego mi brakuje w sposobie ładowania komórek?

MarkPowell
źródło

Odpowiedzi:

380

Musisz ustawić właściwość warstwy masksToBoundsna YES:

cell.previewImage.layer.masksToBounds = YES;

Dzieje się tak, ponieważ UIImageViewformant tworzy pseudo-podwidok do przechowywania UIImageobiektu.

Evan Mulawski
źródło
20
O ile nie rasteryzujesz również widoku (view.layer.shouldRasterize = YES), każda klatka będzie wymagać ponownego zamaskowania wszystkich pikseli.
jjxtra
@jjxtra więc lepiej ustawić shouldRasterize = false?
user924
1
Jeśli shouldRasterize jest fałszywe, płacisz za tworzenie maski narzutu każdej klatki. Jeśli powinno być Rasterize, a twoja warstwa zmienia każdą klatkę, płacisz za maskę i narzut rasteryzacji. Idealnym przypadkiem jest statyczna (niezbyt często zmieniająca się) warstwa z shouldRasterize = true.
jjxtra
35

Warto też to zauważyć

  1. Jeśli używasz funkcji AspectFit AND cornerRadius z clipToBounds / masksToBounds, nie uzyskasz zaokrąglonych rogów.

tj. jeśli masz to

theImageView.contentMode = .scaleAspectFit

i

   theImageView.layer.cornerRadius = (theImageView.frame.size.height)/2
    theImageView.clipsToBounds = true

lub

theImageView.layer.masksToBounds = true

To nie zadziała . będziesz musiał pozbyć się kodu AspectFit

//theImageView.contentMode = .scaleAspectFit
  1. Upewnij się, że szerokość i wysokość widoku obrazu są takie same
Naishta
źródło
W skrócie: ustaw współczynnik proporcji 1: 1, jeśli chcesz korzystać z AspectFit
djdance
22

To powinno działać

cell.previewImage.clipsToBounds = YES;

cell.previewImage.layer.cornerRadius = 20;
Teena nath Paul
źródło
3
Nie jestem pewien, czy clipsToBoundsjest to metoda w późniejszej klasie. Uwierz, że jest masksToBoundsjak powyżej.
Alfie Hanssen
4
Warstwy @AlfieHanssen mają maskiToBounds :, widoki mają clipsToBounds:
Kevin
11

Uważam, że musisz ustawić:

cell.previewImage.layer.masksToBounds = YES;
cell.previewImage.layer.opaque = NO;
Daniel Dickison
źródło
4

W Xcode Interface Builder wybranie atrybutu rysunku „Clip Subviews” dla widoku wraz z ustawieniem promienia narożnika w kodzie cell.previewImage.layer.cornerRadius = 20;robi to za mnie!

Zobacz opcję „Clip Subviews” w IB

koira
źródło
2

Wypróbuj poniższy fragment kodu

cell.previewImage.layer.cornerRadius = 20;
cell.previewImage.clipsToBounds = YES;
Vaibhav Thakre
źródło
2

Wypróbuj ten kod: -

self.imgaviewName.clipsToBounds = true
self.imageviewName.layer.cornerRadius = 10
kangna sharma
źródło
Odpowiedzi zawierające tylko kod są odradzane. Kliknij edytuj i dodaj kilka słów podsumowujących, w jaki sposób Twój kod odpowiada na pytanie, lub może wyjaśnij, w jaki sposób Twoja odpowiedź różni się od poprzedniej odpowiedzi / odpowiedzi. Dzięki
Nick,
1

Dla nie stosuje się, jeżeli obraz jest bardzo duża, w zależności od sprzętu.imageView.contentMode = .scaleAspectFillcornerRadius

Niektóre testy z obrazami panoramicznymi o zmienionym rozmiarze:

  • iPhone X, rozmiar obrazu 5000x1107: 🚫 4000x886: ✅
  • iPhone 6s Plus, rozmiar obrazu 10000x2215: 🚫 5000x1107: ✅
  • iPhone 6s, rozmiar obrazu 10000x2215: 🚫 5000x1107: ✅

Wymiary imageView to 160x100. Co ciekawe, nowszy sprzęt niekoniecznie jest bardziej wydajny.

Zapraszam do edycji tego posta z większą liczbą wyników testów!

Ortwin Gentz
źródło
0
-(void) viewDidAppear:(BOOL)animated{
       [super viewDidAppear:animated];
       [self setMaskTo:viewDistance 
             byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];
           }

- (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners
     {
      UIBezierPath *rounded = [UIBezierPath 
                bezierPathWithRoundedRect:view.bounds
                                              byRoundingCorners:corners

                     cornerRadii:CGSizeMake(20.0, 20.0)];

          CAShapeLayer *shape = [[CAShapeLayer alloc] init];
          shape.frame = self.view.bounds;
         [shape setPath:rounded.CGPath];
          view.layer.mask = shape;
       }
Maulik Patel
źródło
0

Odpowiedź Swift 4.2:

Aby promień narożnika działał, dodaj obraz do a, UIViewa następnie musisz ustawić właściwość obrazu masksToBoundsna true:

planeImage.layer.masksToBounds = true
planeImage.layer.cornerRadius = 20

Uwaga: Zastąp liczbę 20 żądaną cornerRadius

IronmanX46
źródło
0

Nic z poprzednich odpowiedzi nie działa?

Może się zdarzyć, że rozmiar UIImageView jest większy niż rozmiar obrazu. Promień naroża można ustawić dobrze, ale w takim przypadku nie jest on widoczny.

Szybkie sprawdzenie rozmiaru UIImageView według kodu: (lub można użyć narzędzia „Wyświetl hierarchię interfejsu użytkownika” w XCode)

self.imageView.backgroundColor = [UIColor greenColor]; 

W tym scenariuszu należy upewnić się, że UIImageView ma ten sam współczynnik proporcji co obraz.

Marek Manduch
źródło