Chuyển đổi UIS trong ô UITableView


82

Làm cách nào tôi có thể nhúng UISwitchmột UITableViewô vào một ô? Có thể xem các ví dụ trong menu cài đặt.

Giải pháp hiện tại của tôi:

UISwitch *mySwitch = [[[UISwitch alloc] init] autorelease];
cell.accessoryView = mySwitch;

3
Có gì sai với cách bạn đang làm hiện tại?
MobileMon

Câu trả lời:


193

Đặt nó làm phụ kiệnXem thường là cách để thực hiện. Bạn có thể thiết lập nó trong tableView:cellForRowAtIndexPath: Bạn có thể muốn sử dụng target / action để làm điều gì đó khi công tắc được bật. Như vậy:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    switch( [indexPath row] ) {
        case MY_SWITCH_CELL: {
            UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:@"SwitchCell"];
            if( aCell == nil ) {
                aCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"SwitchCell"] autorelease];
                aCell.textLabel.text = @"I Have A Switch";
                aCell.selectionStyle = UITableViewCellSelectionStyleNone;
                UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
                aCell.accessoryView = switchView;
                [switchView setOn:NO animated:NO];
                [switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
                [switchView release];
            }
            return aCell;
        }
        break;
    }
    return nil;
}

- (void)switchChanged:(id)sender {
    UISwitch *switchControl = sender;
    NSLog( @"The switch is %@", switchControl.on ? @"ON" : @"OFF" );
}

1
Thay vì MY_SWITCH_CELL phải là số ô tương ứng tôi nghĩ. Giải pháp tuyệt vời!
kiểm tra

1
@Jesse 'aCell.accessoryView = switchView;' hoàn toàn tương đương với '[aCell setAccessoryView: switchView];'. Bạn có lý do gì để tránh ký hiệu dấu chấm không?
zpasternack

1
Cảm ơn rất nhiều cho câu trả lời này! Việc thêm nút chuyển làm chế độ xem phụ sẽ làm rối loạn giọng nói qua các lệnh. Đặt nó làm chế độ xem phụ kiện hoạt động hoàn hảo với lồng tiếng!
Nitin Alabur

2
Làm thế nào để biết chỉ số của công tắc được chọn?
doxsi

2
@doxsi switchView.tag = indexPath.rowđể phát hiện chuyển đổi hàng nào Đã thay đổi nhanh chóng
Nazmul Hasan

10

Bạn có thể thêm UISwitch hoặc bất kỳ điều khiển nào khác vào ô accessoryView. Bằng cách đó, nó sẽ xuất hiện ở phía bên phải của ô, có thể là những gì bạn muốn.


8
if (indexPath.row == 0) {//If you want UISwitch on particular row
    UISwitch *theSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
    [cell addSubview:theSwitch];
    cell.accessoryView = theSwitch;
}

Tại sao bạn sử dụng initWithFrame? Tại sao bạn sử dụng addSubview? switchkhông thể được sử dụng như một tên biến.
thử nghiệm

Xin lỗi cho tên chuyển đổi. Tôi đã có một số mã .. Tôi chỉ cần thay đổi tên biến trong đó.
k-thorat

Nó đã làm việc cho tôi. Giải pháp hiệu quả với ít mã hơn.
Kenan Karakecili

2
Tôi có thể thực hiện công việc này bằng cách chỉ thiết lập thuộc tính AccessoriesView của ô. Tôi không nghĩ rằng việc thêm nút chuyển làm lượt xem phụ là cần thiết.
johnnieb

2

Bạn có thể chuẩn bị ô trong Interfacebuilder, liên kết nó với IBOutlet của Viewcontroller của bạn và trả lại nó khi tableview yêu cầu hàng thích hợp.

Thay vào đó, bạn có thể tạo một xib riêng biệt cho ô (lại với IB) và tải nó bằng UINib khi tạo ô.

Cuối cùng, bạn có thể tạo chuyển đổi theo chương trình và thêm nó vào chế độ xem nội dung hoặc chế độ xem phụ kiện của ô của bạn.

Cái nào phù hợp với bạn nhất phần lớn phụ thuộc vào những gì bạn thích làm. Nếu nội dung số lần xem bảng của bạn được sửa (đối với trang cài đặt, v.v.) thì hai nội dung đầu tiên có thể hoạt động tốt, nếu nội dung động, tôi thích giải pháp có lập trình hơn. Vui lòng trình bày cụ thể hơn về những gì bạn muốn làm, điều này sẽ giúp trả lời câu hỏi của bạn dễ dàng hơn.


Tôi thích giải pháp có lập trình hơn (mặc dù nó dành cho trang cài đặt), nhưng tôi cũng quan tâm đến cách hoạt động của hai tùy chọn đầu tiên. Có lẽ bạn có thể giải thích chúng chi tiết hơn một chút.
kiểm tra

1

Đây là một giải pháp hoàn chỉnh hơn, trong đó việc tắt và bật diễn ra trên lớp xem (UITableViewCell) và nó chuyển tiếp các sự kiện tới người đại diện tableView thông qua didSelectdidDeselect:

class CustomCell: UITableViewCell {
    private lazy var switchControl: UISwitch = {
        let s = UISwitch()
        s.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
        return s
    }()

    override func awakeFromNib() {
        self.accessoryView = switchControl
        self.selectionStyle = .none // to show the selection style only on the UISwitch
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        (self.accessoryView as? UISwitch)?.isOn = selected
    }

    @objc private func switchValueDidChange(_ sender: UISwitch) { // needed to treat switch changes as if the cell was selected/unselected
        guard let tv = self.superview as? UITableView, let ip = tv.indexPath(for: self) else {
            fatalError("Unable to cast self.superview as UITableView or get indexPath")
        }
        setSelected(sender.isOn, animated: true)
        if sender.isOn {
            tv.delegate?.tableView?(tv, didSelectRowAt: ip)
        } else {
            tv.delegate?.tableView?(tv, didDeselectRowAt: ip)
        }
    }
}

Và trên đại diện của bạn


func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    return false // to disable interaction since it happens on the switch
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // to make sure it is rendered correctly when dequeuing:
    // stuff
    if isSelected { // stored value to know if the switch is on or off
        tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
    } else {
        tableView.deselectRow(at: indexPath, animated: true)
    }
    // more stuff
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // do your thing when selecting
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    // do your thing when deselecting
}

0

cho người dùng nhanh

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "TableIdentifer")
        let switch = UISwitch()
        cell.accessoryView = switch 
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.