Poszedłem dalej i dostosowałem willDisplayCell, aby uzyskać lepszą symulację stylów komórek w aplikacji ustawień.
Cel C
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(tintColor)]) {
if (tableView == self.tableView) {
CGFloat cornerRadius = 5.f;
cell.backgroundColor = UIColor.clearColor;
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
CGMutablePathRef pathRef = CGPathCreateMutable();
CGRect bounds = CGRectInset(cell.bounds, 10, 0);
BOOL addLine = NO;
if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) {
CGPathAddRoundedRect(pathRef, nil, bounds, cornerRadius, cornerRadius);
} else if (indexPath.row == 0) {
CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetMidX(bounds), CGRectGetMinY(bounds), cornerRadius);
CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));
addLine = YES;
} else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) {
CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds), CGRectGetMidX(bounds), CGRectGetMaxY(bounds), cornerRadius);
CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
} else {
CGPathAddRect(pathRef, nil, bounds);
addLine = YES;
}
layer.path = pathRef;
CFRelease(pathRef);
layer.fillColor = [UIColor colorWithWhite:1.f alpha:0.8f].CGColor;
if (addLine == YES) {
CALayer *lineLayer = [[CALayer alloc] init];
CGFloat lineHeight = (1.f / [UIScreen mainScreen].scale);
lineLayer.frame = CGRectMake(CGRectGetMinX(bounds)+10, bounds.size.height-lineHeight, bounds.size.width-10, lineHeight);
lineLayer.backgroundColor = tableView.separatorColor.CGColor;
[layer addSublayer:lineLayer];
}
UIView *testView = [[UIView alloc] initWithFrame:bounds];
[testView.layer insertSublayer:layer atIndex:0];
testView.backgroundColor = UIColor.clearColor;
cell.backgroundView = testView;
}
}
}
Szybki
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if (cell.respondsToSelector(Selector("tintColor"))){
if (tableView == self.tableView) {
let cornerRadius : CGFloat = 12.0
cell.backgroundColor = UIColor.clearColor()
var layer: CAShapeLayer = CAShapeLayer()
var pathRef:CGMutablePathRef = CGPathCreateMutable()
var bounds: CGRect = CGRectInset(cell.bounds, 25, 0)
var addLine: Bool = false
if (indexPath.row == 0 && indexPath.row == tableView.numberOfRowsInSection(indexPath.section)-1) {
CGPathAddRoundedRect(pathRef, nil, bounds, cornerRadius, cornerRadius)
} else if (indexPath.row == 0) {
CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds))
CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetMidX(bounds), CGRectGetMinY(bounds), cornerRadius)
CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius)
CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))
addLine = true
} else if (indexPath.row == tableView.numberOfRowsInSection(indexPath.section)-1) {
CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds))
CGPathAddArcToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds), CGRectGetMidX(bounds), CGRectGetMaxY(bounds), cornerRadius)
CGPathAddArcToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius)
CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds))
} else {
CGPathAddRect(pathRef, nil, bounds)
addLine = true
}
layer.path = pathRef
layer.fillColor = UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 0.8).CGColor
if (addLine == true) {
var lineLayer: CALayer = CALayer()
var lineHeight: CGFloat = (1.0 / UIScreen.mainScreen().scale)
lineLayer.frame = CGRectMake(CGRectGetMinX(bounds)+10, bounds.size.height-lineHeight, bounds.size.width-10, lineHeight)
lineLayer.backgroundColor = tableView.separatorColor.CGColor
layer.addSublayer(lineLayer)
}
var testView: UIView = UIView(frame: bounds)
testView.layer.insertSublayer(layer, atIndex: 0)
testView.backgroundColor = UIColor.clearColor()
cell.backgroundView = testView
}
}
}
Szybki 3
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cornerRadius: CGFloat = 5
cell.backgroundColor = .clear
let layer = CAShapeLayer()
let pathRef = CGMutablePath()
let bounds = cell.bounds.insetBy(dx: 20, dy: 0)
var addLine = false
if indexPath.row == 0 && indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
pathRef.__addRoundedRect(transform: nil, rect: bounds, cornerWidth: cornerRadius, cornerHeight: cornerRadius)
} else if indexPath.row == 0 {
pathRef.move(to: .init(x: bounds.minX, y: bounds.maxY))
pathRef.addArc(tangent1End: .init(x: bounds.minX, y: bounds.minY), tangent2End: .init(x: bounds.midX, y: bounds.minY), radius: cornerRadius)
pathRef.addArc(tangent1End: .init(x: bounds.maxX, y: bounds.minY), tangent2End: .init(x: bounds.maxX, y: bounds.midY), radius: cornerRadius)
pathRef.addLine(to: .init(x: bounds.maxX, y: bounds.maxY))
addLine = true
} else if indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
pathRef.move(to: .init(x: bounds.minX, y: bounds.minY))
pathRef.addArc(tangent1End: .init(x: bounds.minX, y: bounds.maxY), tangent2End: .init(x: bounds.midX, y: bounds.maxY), radius: cornerRadius)
pathRef.addArc(tangent1End: .init(x: bounds.maxX, y: bounds.maxY), tangent2End: .init(x: bounds.maxX, y: bounds.midY), radius: cornerRadius)
pathRef.addLine(to: .init(x: bounds.maxX, y: bounds.minY))
} else {
pathRef.addRect(bounds)
addLine = true
}
layer.path = pathRef
layer.fillColor = UIColor(white: 1, alpha: 0.8).cgColor
if (addLine == true) {
let lineLayer = CALayer()
let lineHeight = 1.0 / UIScreen.main.scale
lineLayer.frame = CGRect(x: bounds.minX + 10, y: bounds.size.height - lineHeight, width: bounds.size.width - 10, height: lineHeight)
lineLayer.backgroundColor = tableView.separatorColor?.cgColor
layer.addSublayer(lineLayer)
}
let testView = UIView(frame: bounds)
testView.layer.insertSublayer(layer, at: 0)
testView.backgroundColor = .clear
cell.backgroundView = testView
}
Swift 4.2
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if (cell.responds(to: #selector(getter: UIView.tintColor))){
if tableView == self.tableView {
let cornerRadius: CGFloat = 12.0
cell.backgroundColor = .clear
let layer: CAShapeLayer = CAShapeLayer()
let path: CGMutablePath = CGMutablePath()
let bounds: CGRect = cell.bounds
bounds.insetBy(dx: 25.0, dy: 0.0)
var addLine: Bool = false
if indexPath.row == 0 && indexPath.row == ( tableView.numberOfRows(inSection: indexPath.section) - 1) {
path.addRoundedRect(in: bounds, cornerWidth: cornerRadius, cornerHeight: cornerRadius)
} else if indexPath.row == 0 {
path.move(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.addArc(tangent1End: CGPoint(x: bounds.minX, y: bounds.minY), tangent2End: CGPoint(x: bounds.midX, y: bounds.minY), radius: cornerRadius)
path.addArc(tangent1End: CGPoint(x: bounds.maxX, y: bounds.minY), tangent2End: CGPoint(x: bounds.maxX, y: bounds.midY), radius: cornerRadius)
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
} else if indexPath.row == (tableView.numberOfRows(inSection: indexPath.section) - 1) {
path.move(to: CGPoint(x: bounds.minX, y: bounds.minY))
path.addArc(tangent1End: CGPoint(x: bounds.minX, y: bounds.maxY), tangent2End: CGPoint(x: bounds.midX, y: bounds.maxY), radius: cornerRadius)
path.addArc(tangent1End: CGPoint(x: bounds.maxX, y: bounds.maxY), tangent2End: CGPoint(x: bounds.maxX, y: bounds.midY), radius: cornerRadius)
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
} else {
path.addRect(bounds)
addLine = true
}
layer.path = path
layer.fillColor = UIColor.white.withAlphaComponent(0.8).cgColor
if addLine {
let lineLayer: CALayer = CALayer()
let lineHeight: CGFloat = 1.0 / UIScreen.main.scale
lineLayer.frame = CGRect(x: bounds.minX + 10.0, y: bounds.size.height - lineHeight, width: bounds.size.width, height: lineHeight)
lineLayer.backgroundColor = tableView.separatorColor?.cgColor
layer.addSublayer(lineLayer)
}
let testView: UIView = UIView(frame: bounds)
testView.layer.insertSublayer(layer, at: 0)
testView.backgroundColor = .clear
cell.backgroundView = testView
}
}
}
[UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:corner cornerRadii:cornerSize];
W iOS 13 i nowszych ten styl tabeli jest ostatecznie udostępniany przez Apple, bez konieczności ponownego projektowania, dzięki nowemu UITableView.Style.insetGrouped stylem widoku tabeli .
W Xcode 11 i nowszych można to ustawić w ustawieniach konstruktora interfejsu dla widoku tabeli, wybierając opcję Inset Grouped dla stylu:
źródło
Odpowiadając @NarasimhaiahKolli, w jaki sposób ustawiam widok tła komórki, aby cała komórka nie wyglądała tak, jakby była podświetlona. Mam nadzieję że to pomoże.
źródło
Odpowiedź @jvanmetre jest świetna i działa. Opierając się na tym i zgodnie z sugestią @SergiySalyuk w komentarzach. Zaktualizowałem kod, aby korzystał z UIBezierPath, dzięki czemu jest łatwiejszy do zrozumienia i nieco szybszy.
Moja wersja naprawia również błąd separatora i dodaje wybrany widok tła, który pasuje do komórki.
Pamiętaj, aby ustawić widok tabeli na brak separatora:
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
Cel C
źródło
Próbowałem osiągnąć ten sam zaokrąglony wygląd aplikacji Ustawienia na komórkach tableviewcells. Moja odpowiedź jest również oparta na odpowiedzi SO, jak ustawić cornerRadius tylko dla lewego górnego i prawego górnego rogu UIView? .
źródło
Po wypróbowaniu niektórych odpowiedzi tutaj, zdecydowałem się pójść na całość i zaimplementować całą podklasę oprócz
UITableView
iUITableViewCell
powielić zaokrąglony styl widoku tabeli zgrupowanej w iOS 7.https://github.com/TimOliver/TORoundedTableView
Okazało się, że był to bardzo skomplikowany proces:
layoutSubviews
wUITableView
celu relayout każdą komórkę i akcesoriów widok tak były już od krawędzi do krawędzi.UITableViewCell
, aby usunąć górny i dolny widok linii włosów separatora (ale pozostawiając nietknięte te wewnątrz sekcji).UITableViewCell
widok tła, który opcjonalnie mógł mieć zaokrąglone rogi na górze i na dole, aby można go było użyć dla pierwszej i ostatniej komórki w każdej sekcji. Elementy te miały naCALayer
celu uniknięcieUITableView
ukrytego zachowania polegającego na zmianie koloru widoków tła, gdy użytkownik dotknie komórki.CALayer
instancje, na które nie reagująlayoutSubviews
, musiałem następnie zrobić trochę majsterkowania w ramach animacji podstawowej, aby upewnić się, że rozmiar górnych i dolnych komórek zmienia się z taką samą prędkością jak inne komórki, gdy użytkownik obraca urządzenie.Podsumowując, jest to możliwe, ale ponieważ wymaga to sporego wysiłku i kosztuje niewielką ilość wydajności (ponieważ nieustannie walczy z kodem Apple, próbując wszystko cofnąć), najlepiej jest złożyć radar z prośbą Apple o to. oficjalnie eksponuj ten styl. Do tego czasu zachęcam do korzystania z mojej biblioteki. :)
źródło
Stworzyłem metodę o nazwie
addRoundedCornersWithRadius:(CGFloat)radius ForCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
która utworzy zaokrąglone rogi na górze i na dole każdej sekcji.Zaletą używania
maskView
właściwości ofUITableViewCell
jest to, że po zaznaczeniu komórki zaokrąglone rogi są nadal widoczne.źródło
Moja odpowiedź może być za późno, ale dla wersji Swift (dowolnej) z pewnością będzie przydatna i bardzo łatwa w użyciu.
PS: Użyłem następującego kodu dla Swift 3.0.
źródło
działający kod dla swift ... tak naprawdę robimy, jeśli sekcja ma tylko jeden wiersz, to robimy to ze wszystkich stron, jeśli sekcja ma wiele wierszy, robimy to na górze w pierwszym wierszu i na dole w ostatnim wierszu ... właściwości BottomLeft, BottomRight, topLeft, TopRight powinny być typu rect corner (Sugestie z xcode podczas pisania ... istnieje inny narożnik zawartości właściwości o tej samej nazwie ... więc sprawdź to)
źródło
Obawiam się, że nie ma na to łatwego sposobu. Będziesz musiał dostosować swoje UITableViewCell, coś takiego działa:
Ustaw styl tableView na grouped.
Ustaw kolor tła TableView, aby wyczyścić kolor.
Na swoim -
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)
wyczyść tło komórki i utwórz UIView z pożądanymi zaokrąglonymi rogami jako tłem. Coś takiego:Może być konieczne dalsze polerowanie, ale to jest główna idea.
źródło
Chciałem osiągnąć to samo, ale z obramowaniem wokół każdej sekcji (linia w iOS6). Ponieważ nie znalazłem łatwej modyfikacji sugerowanych rozwiązań, wymyśliłem własne. Jest to modyfikacja odpowiedzi udzielonej przez @Roberto Ferraz w tym temacie. Utworzyłem niestandardową klasę, która dziedziczy po UITableViewCell. Dodałem w nim widok kontenera o odpowiednim rozmiarze (u mnie obkurczony z obu stron o 15px). Niż w klasie zrobiłem to:
Następnie w swoim źródle danych robisz to:
I voila - masz zaokrąglone rogi ORAZ obramowania na swoich odcinkach.
Mam nadzieję że to pomoże!
PS Dokonałem kilku zmian, ponieważ znalazłem kilka błędów w oryginalnym kodzie - głównie nie ustawiłem wszystkich wartości we wszystkich przypadkach, co powoduje bardzo oszałamiające efekty przy ponownym użyciu komórek :)
źródło
swift 4 Jeśli chcesz dołączyć również nagłówek sekcji, spróbuj poniżej
zadeklaruj cornerLayerWidth jako zmienną globalną
var cornerLayerWidth: CGFloat = 0,0
i
źródło
W Swift 4.2:
Używać:
Jeśli komórka jest pierwszą komórką w grupie, ustaw
top = True
, jeśli jest to ostatnia komórkabottom = true
, jeśli komórka jest jedyną w grupie, ustaw oba natrue
.Jeśli chcesz bardziej lub mniej zaokrąglone, po prostu zmień radia z 10 na inną wartość.
źródło
Ten kod ustawi zaokrąglone rogi dla całego widoku tabeli zamiast pojedynczej komórki.
I wyczyść kolor tła każdej komórki w cellForRow
źródło
Dodaj to, aby usunąć górną linię w tableview self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
źródło