Próbuję dodać cień do widoków, które są ułożone jeden na drugim, widoki zwijają się, umożliwiając wyświetlanie zawartości w innych widokach, w tym duchu chcę pozostać view.clipsToBounds
WŁĄCZONY, aby po zwinięciu widoków ich zawartość została obcięta.
Wydaje się, że utrudniło mi to dodanie cienia do warstw, ponieważ po włączeniu clipsToBounds
cienie również są przycinane.
Próbowałem manipulować view.frame
i view.bounds
dodać cień do ramki, ale pozwoliłem, by granice były wystarczająco duże, aby je objąć, jednak nie miałem z tym szczęścia.
Oto kod, którego używam, aby dodać cień (działa tylko z clipsToBounds
WYŁĄCZONYM, jak pokazano)
view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
Oto zrzut ekranu przedstawiający cień nakładany na górną, najjaśniejszą szarą warstwę. Mam nadzieję, że daje to wyobrażenie o tym, jak moje treści będą się nakładać, jeśli clipsToBounds
jest wyłączone.
Jak mogę dodać cień do mojej UIView
i zachować obcięte treści?
Edycja: Chciałem tylko dodać, że bawiłem się również przy użyciu obrazów tła z włączonymi cieniami, co działa dobrze, jednak nadal chciałbym poznać najlepiej zakodowane rozwiązanie do tego.
masksToBounds = NO;
do mojego oryginału - przy obu próbach, które zostawiłemclipsToBounds = YES;
WŁĄCZONE - obie nie udało się przyciąć zawartości. oto zrzut ekranu przedstawiający, co się stało z twoim przykładem> youtu.be/tdpemc_XdpsUIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:5.0];
. Nie testowane, ale powinno dać oczekiwany rezultat.layoutSubviews()
. A jeśli nie zrekompensujemy tego w tym miejscu, dostosowującshadowPath
rozmiar, aby odzwierciedlić bieżący rozmiar, mielibyśmy widok o zmienionym rozmiarze, ale cień nadal miałby stary (początkowy) rozmiar i albo nie byłby wyświetlany, albo wyglądałby tam, gdzie nie powinien .Odpowiedź Wasabii w Swift 2.3:
A w Swift 3/4/5:
Umieść ten kod w module layoutSubviews (), jeśli używasz AutoLayout.
W SwiftUI wszystko jest o wiele łatwiejsze:
źródło
layoutSubviews
CGSize(width: 0, height: 0.5)
view.bounds
nie został stworzony tak oczywiście, żeshadowPath
nie może odnosić się do prostego widoku, aleCGRectZero
zamiast tego. W każdym razie, odłożenie tegolayoutSubviews
w końcu rozwiązało mój problem!Sztuczka polega na
masksToBounds
poprawnym zdefiniowaniu właściwości warstwy widoku:i powinno działać.
( Źródło )
źródło
Możesz utworzyć rozszerzenie dla UIView, aby uzyskać dostęp do tych wartości w edytorze projektu
źródło
Możesz również ustawić cień na swój widok z serii ujęć
źródło
On viewWillLayoutSubviews:
Korzystanie z rozszerzenia UIView:
Stosowanie:
źródło
targetView: UIView
i usuń grzywkę.self
? Wydaje mi się o wiele wygodniejsze.if let
składni zamiast!
Więc tak, powinieneś preferować właściwość shadowPath dla wydajności, ale także: Z pliku nagłówkowego CALayer.shadowPath
Określenie ścieżki jawnie przy użyciu tej właściwości zwykle * poprawia wydajność renderowania, podobnie jak udostępnianie tej samej ścieżki * odniesienia na wielu warstwach
Mniej znaną sztuczką jest udostępnianie tego samego odniesienia na wielu warstwach. Oczywiście muszą używać tego samego kształtu, ale jest to powszechne w przypadku komórek widoku tabeli / kolekcji.
Nie wiem, dlaczego działa szybciej, jeśli udostępniasz instancje, domyślam się, że buforuje renderowanie cienia i może ponownie użyć go w innych instancjach w widoku. Zastanawiam się, czy to jest jeszcze szybsze z
źródło