TableView添加分割线_篱下悠然_新浪博客

   1. // 设置分割线有内容显示,无内容不显示

    self.tableView.tableFooterView = [[UIView alloc] init];




 2. //设置分割线从头显示

//    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {

//        [self.tableView setSeparatorInset:UIEdgeInsetsZero];

    //    }




 3. //设置分割线从10开始显示

self.tableView.separatorInset = UIEdgeInsetsMake(01000);




一般TableView设置全屏分隔线有下面三种方法

1.自定义cell,手动添加分割线 

  • 隐藏自带的
    tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

  • 可以通过addSubview的方式添加一条分割线;也可以自绘分割线。

// 自绘分割线
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillRect(context, rect);

    CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0xE2/255.0f green:0xE2/255.0f blue:0xE2/255.0f alpha:1].CGColor);
    CGContextStrokeRect(context, CGRectMake(0, rect.size.height - 1, rect.size.width, 1));
}

2.重写cell的setFrame方法,高度-1,露出背景色

- (void)setFrame:(CGRect)frame
{
    frame.size.height -= 1;
    // 给cellframe赋值
    [super setFrame:frame];
}
  • 取消系统的分割线
  • 设置tableView背景色为分割线颜色
    // 取消系统分割线
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    // 设置tableView背景色
    self.tableView.backgroundColor = [UIColor colorWithWhite:215 / 255.0 alpha:1];
    

3.利用系统属性设置(separatorInset, layoutMargins)共需添加三句代码:

  • 对tableView的separatorInset, layoutMargins属性的设置
    -(void)viewDidLoad {
      [super viewDidLoad];
      //1.调整(iOS7以上)表格分隔线边距
      if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
          self.tableView.separatorInset = UIEdgeInsetsZero;
      }
      //2.调整(iOS8以上)view边距(或者在cell中设置preservesSuperviewLayoutMargins,二者等效)
      if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
          self.tableView.layoutMargins = UIEdgeInsetsZero;
      }
    }
    
  • 对cell的LayoutMargins属性的设置
对cell的设置可以写在cellForRowAtIndexPath里,也可以写在willDisplayCell方法里

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    FSDiscoverSpecialCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[FSDiscoverSpecialCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }

   //2.调整(iOS8以上)tableView边距(与上面第2步等效,二选一即可)
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        cell.preservesSuperviewLayoutMargins = NO;
    }
   //3.调整(iOS8以上)view边距
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
    return cell;
}

三种方法优缺点比较:

  • 方法1是比较好用的,但是有些情况下系统自带的cell就足够用了,仅仅为了分隔线却还必须再自定义cell,添加一个view,设置背景颜色和frame,又显得麻烦;

  • 方法2比较取巧,但是也需要自定义cell,在某些情况下不允许改变tableView的背景色,使用场景有限;

  • 方法3不需要自定义cell,对系统(iOS7,iOS8以上)做个简单判断即可.可惜网上很多文章写的不对,很多人不会正确使用,有些会用的人也说不清楚原理,只管复制粘贴.
    比如网上流传的一般是这样,需要四步,虽然真的管用,但多了一步[cell setSeparatorInset:UIEdgeInsetsZero];而且原理也没讲,估计是某大神写的,根本不屑于过多解释,让我用起来很郁闷,网上流传代码: 

首先在viewDidLoad方法中加上如下代码:
-(void)viewDidLoad {
    [super viewDidLoad];
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    [self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
然后在willDisplayCell方法中加入如下代码:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
   }
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

其实关于分隔线不能全屏的原理,苹果官方在文件中已经说明了,可以去看一下


在iOS7之前系统默认就是全屏的,iOS7时UITableView多了separatorInset属性,可在UITableView的头文件中查看,如下:

@property (nonatomic) UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; 
// allows customization of the frame of cell separators

iOS7时只要设置该属性为UIEdgeInsetsZero就没有问题了.


iOS8之后仅仅完成以上设置就不行了,仔细查看后发现iOS8的UIView
的头文件里又多了个layoutMargins属性,并有官方注释

@property (nonatomic) UIEdgeInsets layoutMargins NS_AVAILABLE_IOS(8_0);

大意是说:layoutMargins是view的bounds的边距,用来调整内容默认边距

如果preservesSuperviewLayoutMargins属性是YES,那么设置父控件的layoutMargins边距,
就会影响所有子控件的相对于父控件bounds的layoutMargins边距

如果你的view的子类在布局或者绘图中使用了layoutMargins属性,需要重写-layoutMarginsDidChange 方法,
以便当边距改变时能刷新你的view

正是因为layoutMargins是UIView的新增属性,tablet和cell作为UIView的子类都有这个属性,所以相比较iOS7系统,iOS8之后就多了两步,必须同时再对tableView和cell的layoutMargins属性进行处理,才能让分隔线真正全屏.

同时官方注释中对preservesSuperviewLayoutMargins(意即:维持父控件的布局边距)属性的说明,也正好能说明网上另一种方法不设置self.tableView.layoutMargins = UIEdgeInsetsZero;而是设置cell.preservesSuperviewLayoutMargins = NO;为什么也能起作用

弄清楚了这些原理,就可以更好的记忆和使用这些方法,不用每次都去旧代码查找或者去百度了.

说到了最后,不知道大家有没有觉得影响分隔线全屏的元凶layoutMargins属性 稍微有点眼熟呢?其实它在另一个地方也做了不少恶,就在storyboard中:

TableView添加分割线
QQ20150413-000@2x.png


PS:附效果图如下:


设置之前效果图:

TableView添加分割线
QQ20150411-111@2x.png


设置完第1步self.tableView.separatorInset = UIEdgeInsetsZero;后效果图:

TableView添加分割线
QQ20150411-222@2x.png


设置完第2步self.tableView.layoutMargins = UIEdgeInsetsZero;后效果图:

TableView添加分割线
QQ20150411-333@2x.png


设置完第3步cell.layoutMargins = UIEdgeInsetsZero;后效果图:

TableView添加分割线
QQ20150411-444@2x.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以通过以下步骤在JavaFX TableView添加按钮: 1. 创建一个TableView对象,并设置列数和行数。 2. 创建一个TableColumn对象,并设置列名和单元格值。 3. 创建一个Callback对象,用于创建单元格的编辑器和渲染器。 4. 在Callback对象的call方法中,创建一个Button对象,并设置按钮的文本和事件处理程序。 5. 将Button对象添加到单元格中,并返回单元格。 6. 将TableColumn对象添加TableView中。 7. 将数据添加TableView中。 示例代码如下: ``` TableView<Person> tableView = new TableView<>(); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); tableView.setPrefSize(400, 400); TableColumn<Person, String> nameColumn = new TableColumn<>("Name"); nameColumn.setCellValueFactory(new PropertyValueFactory<>("name")); TableColumn<Person, Void> actionColumn = new TableColumn<>("Action"); actionColumn.setCellFactory(new Callback<TableColumn<Person, Void>, TableCell<Person, Void>>() { @Override public TableCell<Person, Void> call(TableColumn<Person, Void> param) { final TableCell<Person, Void> cell = new TableCell<Person, Void>() { private final Button btn = new Button("Delete"); { btn.setOnAction(event -> { Person person = getTableView().getItems().get(getIndex()); getTableView().getItems().remove(person); }); } @Override protected void updateItem(Void item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); } else { setGraphic(btn); } } }; return cell; } }); tableView.getColumns().addAll(nameColumn, actionColumn); ObservableList<Person> data = FXCollections.observableArrayList( new Person("John"), new Person("Mary"), new Person("Tom") ); tableView.setItems(data); public class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` 在上面的示例中,我们创建了一个TableView对象,并添加了两个TableColumn对象:一个用于显示人名,另一个用于显示删除按钮。我们使用了一个Callback对象来创建删除按钮的单元格编辑器和渲染器。在单元格编辑器中,我们创建了一个Button对象,并设置了按钮的文本和事件处理程序。最后,我们将TableColumn对象添加TableView中,并将数据添加TableView中。 ### 回答2: JavaFX TableView表格作为一个组件,提供了在单元格中显示数据的功能。我们还希望TableView中的单元格可以添加按钮,点击按钮后执行特定的操作。下面,我将介绍如何在JavaFX的TableView表格中添加按钮的实现方法。 首先,需要定义一个Button对象。 ```java Button button = new Button("Button"); ``` 接着,在表格中的单元格中添加Button控件。可以通过给单元格设置自定义的TableCell来实现。在TableCell中,需要重写updateItem方法,将Button添加到单元格中,并设置Button的事件处理程序。 ```java TableColumn<User, User> actionColumn = new TableColumn<>(); actionColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue())); actionColumn.setCellFactory(param -> new TableCell<User, User>() { private final Button button = new Button("Button"); { button.setOnAction(event -> { User user = getTableView().getItems().get(getIndex()); // 按钮点击事件处理 }); } @Override protected void updateItem(User user, boolean empty) { super.updateItem(user, empty); if (user == null || empty) { setGraphic(null); } else { setGraphic(button); } } }); tableView.getColumns().add(actionColumn); ``` 在上面的代码中,我们创建了一个名为actionColumn的新TableColumn实例。我们设置了一个cellValueFactory,以将行中的User对象传递给单元格。然后,我们设置了一个自定义的单元格工厂方法setCellFactory,该方法会为每个新创建的单元格调用。在每次创建单元格时,我们都会创建一个新的Button实例,并将其添加到单元格中。我们还可以设置按钮的事件处理程序。 最后,我们将新创建的列添加到表格中,以将新的单元格呈现给用户。 现在,我们已经成功地将按钮添加JavaFX TableView表格中了。当我们单击按钮时,表格会触发按钮事件,并执行指定的操作。感谢您的阅读! ### 回答3: JavaFX提供的TableView是一个用于展示表格数据的控件,可以方便地将数据显示成表格的形式。为了更好的用户体验,我们经常会需要在表格中添加一些按钮,比如删除或编辑某一行数据等。这时候,我们可以使用JavaFX的自定义单元格(Custom Cell)来实现给表格添加按钮的功能。 步骤如下: 1. 创建自定义单元格 ```java public class ButtonCell extends TableCell<DataType, Boolean> { final Button cellButton = new Button("Button Text"); ButtonCell(){ cellButton.setOnAction(new EventHandler<ActionEvent>(){ @Override public void handle(ActionEvent t) { // 在这里添加按钮的逻辑 } }); } // 更新单元格的数据以及按钮状态 @Override protected void updateItem(Boolean t, boolean empty) { super.updateItem(t, empty); if(!empty){ setGraphic(cellButton); } else { setGraphic(null); } } } ``` 2. 在TableView中使用自定义单元格 ```java public class Main extends Application { private TableView<DataType> table = new TableView<>(); private ObservableList<DataType> data = FXCollections.observableArrayList( new DataType("Item 1", 100), new DataType("Item 2", 200), new DataType("Item 3", 300) ); private final HBox hb = new HBox(); public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("Table View嵌入JavaFX按钮"); stage.setWidth(450); stage.setHeight(550); table.setEditable(true); TableColumn col1 = new TableColumn("名称"); col1.setCellValueFactory(new PropertyValueFactory<>("name")); TableColumn col2 = new TableColumn("值"); col2.setCellValueFactory(new PropertyValueFactory<>("value")); TableColumn col3 = new TableColumn<>("按钮"); col3.setCellFactory( new Callback<TableColumn<DataType, Boolean>, TableCell<DataType, Boolean>>() { @Override public TableCell<DataType, Boolean> call(TableColumn<DataType, Boolean> p) { return new ButtonCell(); } } ); table.setItems(data); table.getColumns().addAll(col1, col2, col3); hb.setSpacing(10); hb.setAlignment(Pos.CENTER); hb.getChildren().addAll(addButton, delButton); final VBox vbox = new VBox(); vbox.setSpacing(5); vbox.setPadding(new Insets(10, 0, 0, 10)); vbox.getChildren().addAll(table, hb); ((Group) scene.getRoot()).getChildren().addAll(vbox); stage.setScene(scene); stage.show(); } } ``` 在上面的代码中,我们首先创建了一个自定义单元格ButtonCell,里面包含一个按钮。我们通过ButtonCell类中的updateItem方法来更新单元格的数据以及按钮的状态。接下来,在TableView中加入了一个新的列col3,使用setCellFactory函数和ButtonCell类将自定义单元格添加到表格列中。最后,我们使用VBox来将TableView和按钮布局在一起,并将其添加到场景(Scene)中。 通过以上步骤,我们就成功地将一个按钮添加到了TableView中。需要注意的是,自定义单元格类ButtonCell可以根据需要修改,每个单元格包含的按钮可以执行不同的操作和逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值