iOS 7 TableView как в настройках приложения на iPad
Я хочу иметь группу UITableView со стилем же, как приложение настройки iPad вид на iOS 7.
это tableView с закругленным углом. Пожалуйста, проверьте приложение для деталей.
Это некоторые настройки по умолчанию, чтобы сделать его похожим, или нам нужно сделать некоторые пользовательские чертежи для того же.
любой намек в правильном направлении будет оценен по достоинству.
спасибо
15 ответов:
Я пошел дальше и дополнительно настроил willDisplayCell, чтобы получить лучшее моделирование стилей ячеек в приложении Настройки.
С
- (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; } } }
Свифт
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 } } }
Swift 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 }
отвечая @NarasimhaiahKolli, о том, как я установил фоновый вид ячейки, чтобы вся ячейка не выглядела так, как будто она выделена. Надеюсь, это поможет.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { InfoCell *cell; ... if ([cell respondsToSelector:@selector(tintColor)]) { cell.selectedBackgroundView = [self backgroundCellView:cell indexPath:indexPath tableView:tableView]; } return cell; } - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([cell respondsToSelector:@selector(tintColor)]) { cell.backgroundColor = UIColor.clearColor; UIColor *cellColor = [UIColor colorWithWhite:0.90f alpha:.95f]; CAShapeLayer *layer = [self tableView:tableView layerForCell:cell forRowAtIndexPath:indexPath withColor:cellColor]; CGRect bounds = CGRectInset(cell.bounds, 10, 0); UIView *testView = [[UIView alloc] initWithFrame:bounds]; [testView.layer insertSublayer:layer atIndex:0]; testView.backgroundColor = UIColor.clearColor; cell.backgroundView = testView; } } - (UIView *)backgroundCellView:(InfoCell *)cell indexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView { UIColor *cellColor = [UIColor lightGrayColor]; CAShapeLayer *layer = [self tableView:tableView layerForCell:cell forRowAtIndexPath:indexPath withColor:cellColor]; CGRect bounds = CGRectInset(cell.bounds, 10, 0); UIView *testView = [[UIView alloc] initWithFrame:bounds]; [testView.layer insertSublayer:layer atIndex:0]; return testView; } - (CAShapeLayer *)tableView:(UITableView *)tableView layerForCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath withColor:(UIColor *)color { CGFloat cornerRadius = 5.f; 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:1.0f].CGColor; layer.fillColor = color.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]; } return layer; }
ответ @jvanmetre велик, и он работает. Здание поверх него и как предложил @SergiySalyuk в комментариях. Я обновил код, чтобы использовать UIBezierPath вместо того, чтобы сделать его проще для понимания и немного быстрее.
моя версия также исправляет ошибку разделителя и добавляет выбранный фоновый вид, который соответствует ячейке.
Не забудьте установить табличное представление без разделителя:
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
С
- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath { // Set transparent background so we can see the layer cell.backgroundColor = UIColor.clearColor; // Declare two layers: one for the background and one for the selecetdBackground CAShapeLayer *backgroundLayer = [CAShapeLayer layer]; CAShapeLayer *selectedBackgroundLayer = [[CAShapeLayer alloc] init]; CGRect bounds = CGRectInset(cell.bounds, 0, 0);//Cell bounds feel free to adjust insets. BOOL addSeparator = NO;// Controls if we should add a seperator // Determine which corners should be rounded if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) { // This is the only row in its section, round all corners backgroundLayer.path = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(7, 7)].CGPath; } else if (indexPath.row == 0) { // First row, round the top two corners. backgroundLayer.path = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(7, 7)].CGPath; addSeparator = YES; } else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) { // Bottom row, round the bottom two corners. backgroundLayer.path = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(7, 7)].CGPath; } else { // Somewhere between the first and last row don't round anything but add a seperator backgroundLayer.path = [UIBezierPath bezierPathWithRect:bounds].CGPath;// So we have a background addSeparator = YES; } // Copy the same path for the selected background layer selectedBackgroundLayer.path = CGPathCreateCopy(backgroundLayer.path); // Yay colors! backgroundLayer.fillColor = [UIColor colorWithWhite:1.f alpha:0.8f].CGColor; selectedBackgroundLayer.fillColor = [UIColor grayColor].CGColor; // Draw seperator if necessary if (addSeparator == YES) { CALayer *separatorLayer = [CALayer layer]; CGFloat separatorHeight = (1.f / [UIScreen mainScreen].scale); separatorLayer.frame = CGRectMake(CGRectGetMinX(bounds)+10, bounds.size.height-separatorHeight, bounds.size.width-10, separatorHeight); separatorLayer.backgroundColor = tableView.separatorColor.CGColor; [backgroundLayer addSublayer:separatorLayer]; } // Create a UIView from these layers and set them to the cell's .backgroundView and .selectedBackgroundView UIView *backgroundView = [[UIView alloc] initWithFrame:bounds]; [backgroundView.layer insertSublayer:backgroundLayer atIndex:0]; backgroundView.backgroundColor = UIColor.clearColor; cell.backgroundView = backgroundView; UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:bounds]; [selectedBackgroundView.layer insertSublayer:selectedBackgroundLayer atIndex:0]; selectedBackgroundView.backgroundColor = UIColor.clearColor; cell.selectedBackgroundView = selectedBackgroundView; }
попробовав некоторые ответы здесь, я решил пойти всей свиньей и реализовать весь подкласс поверх
UITableView
иUITableViewCell
для репликации округленного сгруппированного стиля представления таблицы в iOS 7.https://github.com/TimOliver/TORoundedTableView
это оказалось очень сложным процессом:
- я должен был подкласс
layoutSubviews
наUITableView
для ретрансляции каждой ячейки и аксессуара посмотреть, чтобы они больше не были от края до края.- я должен был подкласс
UITableViewCell
для того, чтобы удалить верхний и Нижний разделитель волосяного покрова (но оставив те, которые находятся внутри раздела нетронутыми).- затем я создал пользовательский
UITableViewCell
фоновый вид, который может дополнительно иметь закругленные углы сверху и снизу, которые будут использоваться для первой и последней ячеек в каждом разделе. Эти элементы должны были бытьCALayer
избежатьUITableView
неявное поведение изменения цвета фоновые представления, когда пользователь нажимает на ячейку.- потому что они теперь
CALayer
экземпляры, которые не отвечают наlayoutSubviews
, затем мне пришлось сделать некоторую основную анимацию, чтобы обеспечить изменение размеров верхней и нижней ячеек с той же скоростью, что и другие ячейки, когда пользователь вращает устройство.в целом, это возможно сделать, но поскольку это требует значительных усилий и стоит небольшого количества производительности (так как он постоянно борется с кодом Apple, пытаясь установить все назад), возможно, лучше всего подать радар с Apple, требуя, чтобы они официально выставили этот стиль. До тех пор, не стесняйтесь использовать мою библиотеку. :)
Я пытался достичь тех же настроек приложения округлый вид на tableviewcells. Мой ответ также основан на так ответ для Как установить cornerRadius только для верхнего левого и верхнего правого угла UIView?.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; [cell setClipsToBounds:YES]; // rowsArray has cell titles for current group NSArray *rowsArray = [self.sectionsArray objectAtIndex:indexPath.section]; [[cell textLabel] setText:[rowsArray objectAtIndex:indexPath.row]]; float cornerSize = 11.0; // change this if necessary // round all corners if there is only 1 cell if (indexPath.row == 0 && [rowsArray count] == 1) { UIBezierPath *maskPath; maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(cornerSize, cornerSize)]; CAShapeLayer *mlayer = [[CAShapeLayer alloc] init]; mlayer.frame = cell.bounds; mlayer.path = maskPath.CGPath; cell.layer.mask = mlayer; } // round only top cell and only top-left and top-right corners else if (indexPath.row == 0) { UIBezierPath *maskPath; maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(cornerSize, cornerSize)]; CAShapeLayer *mlayer = [[CAShapeLayer alloc] init]; mlayer.frame = cell.bounds; mlayer.path = maskPath.CGPath; cell.layer.mask = mlayer; } // round bottom-most cell of group and only bottom-left and bottom-right corners else if (indexPath.row == [rowsArray count] - 1) { UIBezierPath *maskPath; maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(cornerSize, cornerSize)]; CAShapeLayer *mlayer = [[CAShapeLayer alloc] init]; mlayer.frame = cell.bounds; mlayer.path = maskPath.CGPath; cell.layer.mask = mlayer; } }
Я создал метод, называемый
addRoundedCornersWithRadius:(CGFloat)radius ForCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
что позволит создать закругленные углы в верхней и нижней части каждой секции.преимущества использования
maskView
собственностьUITableViewCell
это то, что при выборе ячейки закругленные углы все еще видны.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"]; [cell.textLabel setText:[NSString stringWithFormat:@"Row %d in Section %d", indexPath.row, indexPath.section]]; [tableView addRoundedCornersWithRadius:12.0f ForCell:cell atIndexPath:indexPath]; return cell; } - (void)addRoundedCornersWithRadius:(CGFloat)radius ForCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { NSInteger MBRows = [self numberOfRowsInSection:indexPath.section] - 1; CAShapeLayer *MBLayer = [[CAShapeLayer alloc] init]; CGRect cellBounds = CGRectMake(0, 0, self.bounds.size.width, cell.bounds.size.height); BOOL shouldAddSeperator = NO; if (indexPath.row == 0 && indexPath.row == MBRows) { [MBLayer setPath:[UIBezierPath bezierPathWithRoundedRect:cellBounds cornerRadius:radius].CGPath]; } else if (indexPath.row == 0) { [MBLayer setPath:[UIBezierPath bezierPathWithRoundedRect:cellBounds byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) cornerRadii:CGSizeMake(radius, radius)].CGPath]; shouldAddSeperator = YES; } else if (indexPath.row == MBRows) { [MBLayer setPath:[UIBezierPath bezierPathWithRoundedRect:cellBounds byRoundingCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) cornerRadii:CGSizeMake(radius, radius)].CGPath]; } else { [MBLayer setPath:[UIBezierPath bezierPathWithRect:cell.bounds].CGPath]; shouldAddSeperator = YES; } [cell setMaskView:[[UIView alloc] initWithFrame:cell.bounds]]; [cell.maskView.layer insertSublayer:MBLayer atIndex:0]; if (shouldAddSeperator == YES) { CGFloat seperator = (1.0f / [UIScreen mainScreen].scale); CALayer *cellSeperator = [[CALayer alloc] init]; [cellSeperator setFrame:CGRectMake(15.0f, cell.bounds.size.height - seperator, cell.bounds.size.width - 15.0f, seperator)]; [cellSeperator setBackgroundColor:self.separatorColor.CGColor]; [cell.layer addSublayer:cellSeperator]; } [cell.maskView.layer setMasksToBounds:YES]; [cell setClipsToBounds:YES]; }
Я хотел добиться того же, но с границей вокруг каждого раздела (линия в iOS6). Поскольку я не нашел легкой модификации предложенных решений, я придумал свой собственный. Это модификация ответа @Roberto Ferraz дал в этой темы. Я создал пользовательский класс, который наследует от UITableViewCell. В нем я добавил вид контейнера с соответствующим размером (в моем случае сжался с обеих сторон с 15px). Чем в классе я это сделал:
- (void)layoutSubviews { [super layoutSubviews]; CGFloat cornerRadius = 10.0f; self.vContainerView.layer.cornerRadius = cornerRadius; self.vContainerView.layer.masksToBounds = YES; self.vContainerView.layer.borderWidth = 1.0f; if (self.top && self.bottom) { // nothing to do - cell is initialized in prepareForReuse } else if (self.top) { // cell is on top - extend height to hide bottom line and corners CGRect frame = self.vContainerView.frame; frame.size.height += cornerRadius; self.vContainerView.frame = frame; self.vSeparatorLine.hidden = NO; } else if (self.bottom) { // cell is on bottom - extend height and shift container view up to hide top line and corners CGRect frame = self.vContainerView.frame; frame.size.height += cornerRadius; frame.origin.y -= cornerRadius; self.vContainerView.frame = frame; self.vSeparatorLine.hidden = YES; } else { // cell is in the middle - extend height twice the height of corners and shift container view by the height of corners - therefore hide top and bottom lines and corners. CGRect frame = self.vContainerView.frame; frame.size.height += (2 * cornerRadius); frame.origin.y -= cornerRadius; self.vContainerView.frame = frame; self.vSeparatorLine.hidden = NO; } } - (void)prepareForReuse { // establish original values when cell is reused CGRect frame = self.vBorderView.frame; frame.size.height = BORDER_VIEW_HEIGHT; frame.origin.y = 0; self.vBorderView.frame = frame; self.vSeparatorLine.hidden = YES; }
затем в ваш источник данных вы делаете это:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... // only one cell in section - must be rounded on top & bottom if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) { cell.top = YES; cell.bottom = YES; } // first cell - must be rounded on top else if (indexPath.row == 0) { cell.top = YES; cell.bottom = NO; } // last cell - must be rounded on bottom else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1) { cell.top = NO; cell.bottom = YES; } else { cell.top = NO; cell.top = NO; } return cell; }
и вуаля - вы получили закругленные углы и границы на ваших секциях.
надеюсь, что это помогает!
П. С. сделал несколько правок, как я нашел некоторые ошибки в исходном коде - в основном я не ставил все значения во всех случаях, которые вызывают некоторые очень потрясающие видеоэффекты, когда клетки были повторно :)
мой ответ может быть слишком поздно, но для Swift версии (любой), это будет, безусловно, полезно и очень легко использовать его.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if (tableView == self.tableViewMovies) { //Top Left Right Corners let maskPathTop = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 5.0, height: 5.0)) let shapeLayerTop = CAShapeLayer() shapeLayerTop.frame = cell.bounds shapeLayerTop.path = maskPathTop.cgPath //Bottom Left Right Corners let maskPathBottom = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 5.0, height: 5.0)) let shapeLayerBottom = CAShapeLayer() shapeLayerBottom.frame = cell.bounds shapeLayerBottom.path = maskPathBottom.cgPath if (indexPath as NSIndexPath).section == 0 { if indexPath.row == 0 { cell.layer.mask = shapeLayerTop }else if indexPath.row == 2 { cell.layer.mask = shapeLayerBottom } }else if (indexPath as NSIndexPath).section == 1 { if indexPath.row == 0 { cell.layer.mask = shapeLayerTop }else { cell.layer.mask = shapeLayerBottom } }else if (indexPath as NSIndexPath).section == 2 { if indexPath.row == 0 { cell.layer.mask = shapeLayerTop }else if indexPath.row == 2 { cell.layer.mask = shapeLayerBottom } } } }
PS: я использовал следующий код для Swift 3.0.
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if (tableView == self.orderDetailsTableView) { //Top Left Right Corners let maskPathTop = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.TopLeft, .TopRight], cornerRadii: CGSize(width: 5.0, height: 5.0)) let shapeLayerTop = CAShapeLayer() shapeLayerTop.frame = cell.bounds shapeLayerTop.path = maskPathTop.CGPath //Bottom Left Right Corners let maskPathBottom = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.BottomLeft, .BottomRight], cornerRadii: CGSize(width: 5.0, height: 5.0)) let shapeLayerBottom = CAShapeLayer() shapeLayerBottom.frame = cell.bounds shapeLayerBottom.path = maskPathBottom.CGPath //All Corners let maskPathAll = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.TopLeft, .TopRight, .BottomRight, .BottomLeft], cornerRadii: CGSize(width: 5.0, height: 5.0)) let shapeLayerAll = CAShapeLayer() shapeLayerAll.frame = cell.bounds shapeLayerAll.path = maskPathAll.CGPath if (indexPath.row == 0 && indexPath.row == tableView.numberOfRowsInSection(indexPath.section)-1) { cell.layer.mask = shapeLayerAll } else if (indexPath.row == 0) { cell.layer.mask = shapeLayerTop } else if (indexPath.row == tableView.numberOfRowsInSection(indexPath.section)-1) { cell.layer.mask = shapeLayerBottom } } }
рабочий код для swift... что на самом деле мы делаем, если раздел имеет только одну строку, то мы делаем это со всех сторон, если раздел имеет несколько строк, то мы делаем это сверху на первой строке и снизу на последней строке... свойства BottomLeft, нижней правой, левой, результаты сравнения должны быть вильный тип угловая(предложения из Xcode, когда вы набираете... существует еще один уголок содержимого свойства с тем же именем.. так что проверьте это)
боюсь, что нет простого способа сделать это. Вам придется настроить свой UITableViewCell, что-то вроде этого работает:
задать стиль вашего TableView для того, чтобы сгруппировать.
установите цвет фона TableView, чтобы очистить цвет.
на -
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)
очистите фон ячейки и создайте UIView с желаемыми закругленными углами в качестве фона. Что-то вроде этого:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; } [cell setBackgroundColor:[UIColor clearColor]]; UIView *roundedView = [[UIView alloc] initWithFrame:cell.frame]; [roundedView setBackgroundColor:[UIColor whiteColor]]; roundedView.layer.cornerRadius = 10.0; [[cell contentView] addSubview:roundedView]; return cell; }
возможно, Вам придется сделать некоторые дальше полировка, но это основная идея.
добавьте это, чтобы удалить верхнюю строку в tableview личность.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
этот проект Git делает именно это. https://github.com/KingIsulgard/iOS-InApp-Settings-TableView
Это очень простой в использовании и учебник о том, как реализовать это очень просто.
swift 4 В случае, если вы хотите включить заголовок раздела также попробуйте ниже one
объявить cornerLayerWidth как глобальную переменную
var cornerLayerWidth:CGFloat = 0.0
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { let cornerRadius: CGFloat = 10 cell.backgroundColor = .clear let layer = CAShapeLayer() let pathRef = CGMutablePath() let bounds = cell.bounds.insetBy(dx: 0, dy: 0) cornerLayerWidth = bounds.width 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 { } 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: 1).cgColor if (addLine == true) { let lineLayer = CALayer() let lineHeight = 1.0 / UIScreen.main.scale lineLayer.frame = CGRect(x: bounds.minX, y: bounds.size.height - lineHeight, width: bounds.size.width , 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 }
и
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let cell = tableView.dequeueReusableCell(withIdentifier: "eMPOIListHeaderViewCell") as! eMPOIListHeaderViewCell let cornerRadius: CGFloat = 10 let layer = CAShapeLayer() let pathRef = CGMutablePath() let bounds = CGRect(x: 0, y: 0, width: cornerLayerWidth, height: 50)//cell.bounds.insetBy(dx: 0, dy: 0) pathRef.__addRoundedRect(transform: nil, rect: bounds, cornerWidth: cornerRadius, cornerHeight: cornerRadius) 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)) layer.path = pathRef layer.fillColor = UIColor(white: 1, alpha: 1).cgColor let lineLayer = CALayer() let lineHeight = 1.0 / UIScreen.main.scale lineLayer.frame = CGRect(x: bounds.minX, y: bounds.size.height - lineHeight, width: bounds.size.width , 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 return cell }
этот код установит закругленные углы для всего представления таблицы вместо одной ячейки.
UIView *roundedView = [[UIView alloc] initWithFrame:CGRectInset(table.frame, 5, 0)]; roundedView.backgroundColor = [UIColor colorWithWhite:1.f alpha:0.8f]; roundedView.layer.cornerRadius = 5.f; [self.view addSubview:roundedView]; [roundedView release]; [self.view addSubview:table];
и очистить цвет фона каждой ячейки в cellForRow
cell.backgroundColor=[UIColor clearColor];