首页 文章

在UITableViewCell中有一个UITextField

提问于
浏览
173

我'm trying to do that for a couple of days now, and after reading tons of messages of people trying to do that too, I'仍然无法在我的某些 UITableViewCells 中完全正常工作 UITextField ,就像在这个例子中一样:

Screenshot

要么我的表单工作,但文本不可见(虽然我将其颜色设置为蓝色),当我点击它时键盘在场上,我无法正确实现键盘事件 . 我尝试了一堆来自Apple的示例(主要是 UICatalog ,其中有一个类似的控件),但它仍然无法正常工作 .

有人可以帮助我(以及所有试图实现这种控制的人)并在 UITableViewCell 中发布 UITextField 的简单实现,这样可以正常工作吗?

12 回答

  • 223

    试试吧 . 对我来说就像一个魅力(在iPhone设备上) . 我将此代码用于登录屏幕一次 . 我将表视图配置为包含两个部分 . 你当然可以摆脱部分条件 .

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:kCellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryNone;
    
        if ([indexPath section] == 0) {
            UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
            playerTextField.adjustsFontSizeToFitWidth = YES;
            playerTextField.textColor = [UIColor blackColor];
            if ([indexPath row] == 0) {
                playerTextField.placeholder = @"example@gmail.com";
                playerTextField.keyboardType = UIKeyboardTypeEmailAddress;
                playerTextField.returnKeyType = UIReturnKeyNext;
            }
            else {
                playerTextField.placeholder = @"Required";
                playerTextField.keyboardType = UIKeyboardTypeDefault;
                playerTextField.returnKeyType = UIReturnKeyDone;
                playerTextField.secureTextEntry = YES;
            }       
            playerTextField.backgroundColor = [UIColor whiteColor];
            playerTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
            playerTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
            playerTextField.textAlignment = UITextAlignmentLeft;
            playerTextField.tag = 0;
            //playerTextField.delegate = self;
    
            playerTextField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
            [playerTextField setEnabled: YES];
    
            [cell.contentView addSubview:playerTextField];
    
            [playerTextField release];
        }
    }
    if ([indexPath section] == 0) { // Email & Password Section
        if ([indexPath row] == 0) { // Email
            cell.textLabel.text = @"Email";
        }
        else {
            cell.textLabel.text = @"Password";
        }
    }
    else { // Login button section
        cell.textLabel.text = @"Log in";
    }
    return cell;    
    }
    

    结果如下所示:

    login form

  • 23

    Here is a solution that looks good under iOS6/7/8/9 .

    Update 2016-06-10: this still works with iOS 9.3.3

    Thanks for all your support, this is now on CocoaPods/Carthage/SPM at https://github.com/fulldecent/FDTextFieldTableViewCell

    基本上我们采取股票 UITableViewCellStyleValue1 并钉一个 UITextField 应该是 detailTextLabel . 这为我们提供了所有场景的自动放置:iOS6 / 7/8/9,iPhone / iPad,图像/无图像,附件/无附件,纵向/横向,1x / 2x / 3x .

    enter image description here

    注意:这是使用storyboard与名为"word"的 UITableViewCellStyleValue1 类型单元格 .

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        cell = [tableView dequeueReusableCellWithIdentifier:@"word"];
        cell.detailTextLabel.hidden = YES;
        [[cell viewWithTag:3] removeFromSuperview];
        textField = [[UITextField alloc] init];
        textField.tag = 3;
        textField.translatesAutoresizingMaskIntoConstraints = NO;
        [cell.contentView addSubview:textField];
        [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:cell.textLabel attribute:NSLayoutAttributeTrailing multiplier:1 constant:8]];
        [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1 constant:8]];
        [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1 constant:-8]];
        [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:cell.detailTextLabel attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
        textField.textAlignment = NSTextAlignmentRight;
        textField.delegate = self;
        return cell;
    }
    
  • 46

    以下是我如何实现这一目标:

    TextFormCell.h

    #import <UIKit/UIKit.h>
    
    #define CellTextFieldWidth 90.0
    #define MarginBetweenControls 20.0
    
    @interface TextFormCell : UITableViewCell {
     UITextField *textField;
    }
    
    @property (nonatomic, retain) UITextField *textField;
    
    @end
    

    TextFormCell.m

    #import "TextFormCell.h"
    
    @implementation TextFormCell
    
    @synthesize textField;
    
    - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {
        if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
      // Adding the text field
      textField = [[UITextField alloc] initWithFrame:CGRectZero];
      textField.clearsOnBeginEditing = NO;
      textField.textAlignment = UITextAlignmentRight;
      textField.returnKeyType = UIReturnKeyDone;
      [self.contentView addSubview:textField];
        }
        return self;
    }
    
    - (void)dealloc {
     [textField release];
        [super dealloc];
    }
    
    #pragma mark -
    #pragma mark Laying out subviews
    
    - (void)layoutSubviews {
     CGRect rect = CGRectMake(self.contentView.bounds.size.width - 5.0, 
            12.0, 
            -CellTextFieldWidth, 
            25.0);
     [textField setFrame:rect];
     CGRect rect2 = CGRectMake(MarginBetweenControls,
           12.0,
             self.contentView.bounds.size.width - CellTextFieldWidth - MarginBetweenControls,
             25.0);
     UILabel *theTextLabel = (UILabel *)[self textLabel];
     [theTextLabel setFrame:rect2];
    }
    

    它可能看起来有点冗长,但它的确有效!

    别忘了设置代表!

  • 9

    试试这个吧 . 它也可以处理滚动,您可以重复使用单元格,而无需删除之前添加的子视图 .

    - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{
        return 10;
    }   
    
    - (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:@"Cell"];
        if( cell == nil)
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease];   
    
        cell.textLabel.text = [[NSArray arrayWithObjects:@"First",@"Second",@"Third",@"Forth",@"Fifth",@"Sixth",@"Seventh",@"Eighth",@"Nineth",@"Tenth",nil] 
                               objectAtIndex:indexPath.row];
    
        if (indexPath.row % 2) {
            UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 21)];
            textField.placeholder = @"Enter Text";
            textField.text = [inputTexts objectAtIndex:indexPath.row/2];
            textField.tag = indexPath.row/2;
            textField.delegate = self;
            cell.accessoryView = textField;
            [textField release];
        } else
            cell.accessoryView = nil;
    
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        return cell;        
    }
    
    - (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
        [inputTexts replaceObjectAtIndex:textField.tag withObject:textField.text];
        return YES;
    }
    
    - (void)viewDidLoad {
        inputTexts = [[NSMutableArray alloc] initWithObjects:@"",@"",@"",@"",@"",nil];
        [super viewDidLoad];
    }
    
  • 0

    这应该不难 . 为表创建单元格时,将UITextField对象添加到单元格的内容视图中

    UITextField *txtField = [[UITextField alloc] initWithFrame....]
    ...
    [cell.contentView addSubview:txtField]
    

    将UITextField的委托设置为self(即viewcontroller)为文本字段指定标记,以便您可以识别在委托方法中编辑的文本字段 . 当用户点击文本字段时,键盘应弹出 . 我让它像这样工作 . 希望能帮助到你 .

  • 2

    每次我的细胞出现时,我都会通过调用一个运行 [cell.contentView bringSubviewToFront:textField] 的方法避免这种情况,但后来我发现了这个相对简单的技术:

    cell.accessoryView = textField;
    

    似乎没有相同的背景覆盖问题,并且它自己(有点)对齐 . 此外,textLabel自动截断以避免溢出(或在其下),这很方便 .

  • 5

    在Swift 3中的UITableViewCell中的UITextField

    详情

    Xcode 8.2.1,Swift 3

    任务

    在UITableViewCell中创建UITextField并将UITextField编辑功能委托给ViewController

    完整示例代码

    类ViewController

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet var tableView: UITableView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            setupTableView()
        }
    }
    
    // MARK: - TableView
    
    extension ViewController {
    
        func setupTableView() {
    
            tableView.dataSource = self
            tableView.tableFooterView = UIView()
    
            let gesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.endEditing))
            tableView.addGestureRecognizer(gesture)
        }
    
        func endEditing() {
            tableView.endEditing(true)
        }
    
    }
    
    // MARK: - UITableViewDataSource
    
    extension ViewController: UITableViewDataSource {
    
        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 2
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldInTableViewCell") as! TextFieldInTableViewCell
            cell.delegate = self
            return cell
        }
    }
    
    // MARK: - TextFieldInTableViewCellDelegate
    
    extension ViewController: TextFieldInTableViewCellDelegate {
    
        func textFieldInTableViewCell(didSelect cell:TextFieldInTableViewCell) {
            if let indexPath = tableView.indexPath(for: cell){
                print("didSelect cell: \(indexPath)")
            }
        }
    
        func textFieldInTableViewCell(cell:TextFieldInTableViewCell, editingChangedInTextField newText:String) {
            if let indexPath = tableView.indexPath(for: cell){
                print("editingChangedInTextField: \"\(newText)\" in cell: \(indexPath)")
            }
        }
    }
    

    class TextFieldInTableViewCell

    import UIKit
    
    class TextFieldInTableViewCell: UITableViewCell {
    
        @IBOutlet var textField: UITextField!
        @IBOutlet var descriptionLabel: UILabel!
    
        var delegate: TextFieldInTableViewCellDelegate?
    
        override func awakeFromNib() {
            super.awakeFromNib()
                    let gesture = UITapGestureRecognizer(target: self, action: #selector(TextFieldInTableViewCell.didSelectCell))
            addGestureRecognizer(gesture)
        }
    
    }
    
    // MARK: - Actions
    
    extension TextFieldInTableViewCell {
    
        func didSelectCell() {
            textField.becomeFirstResponder()
            delegate?.textFieldInTableViewCell(didSelect: self)
        }
    
        @IBAction func textFieldValueChanged(_ sender: UITextField) {
            if let text = sender.text {
                delegate?.textFieldInTableViewCell(cell: self, editingChangedInTextField: text)
            }
        }
    }
    

    协议TextFieldInTableViewCellDelegate

    import UIKit
    
    protocol TextFieldInTableViewCellDelegate {
        func textFieldInTableViewCell(didSelect cell:TextFieldInTableViewCell)
        func textFieldInTableViewCell(cell:TextFieldInTableViewCell, editingChangedInTextField newText:String)
    }
    

    Main.storyboard

    <?xml version="1.0" encoding="UTF-8"?>
    <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
        <device id="retina4_7" orientation="portrait">
            <adaptation id="fullscreen"/>
        </device>
        <dependencies>
            <deployment identifier="iOS"/>
            <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
            <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
            <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
        </dependencies>
        <scenes>
            <!--View Controller-->
            <scene sceneID="tne-QT-ifu">
                <objects>
                    <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_409259" customModuleProvider="target" sceneMemberID="viewController">
                        <layoutGuides>
                            <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                            <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                        </layoutGuides>
                        <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                            <subviews>
                                <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="2cP-ct-Jtg">
                                    <rect key="frame" x="0.0" y="20" width="375" height="647"/>
                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                                    <prototypes>
                                        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="TextFieldInTableViewCell" id="KnN-sc-zHs" customClass="TextFieldInTableViewCell" customModule="stackoverflow_409259" customModuleProvider="target">
                                            <rect key="frame" x="0.0" y="28" width="375" height="44"/>
                                            <autoresizingMask key="autoresizingMask"/>
                                            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KnN-sc-zHs" id="AK1-Th-ke8">
                                                <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
                                                <autoresizingMask key="autoresizingMask"/>
                                                <subviews>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pEG-c7-yoZ">
                                                        <rect key="frame" x="8" y="11" width="77" height="21"/>
                                                        <constraints>
                                                            <constraint firstAttribute="width" constant="77" id="zhu-LA-GOo"/>
                                                        </constraints>
                                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                    <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="text" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="O1l-cp-c2b">
                                                        <rect key="frame" x="93" y="6" width="256" height="31"/>
                                                        <nil key="textColor"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                        <textInputTraits key="textInputTraits"/>
                                                        <connections>
                                                            <action selector="textFieldValueChanged:" destination="KnN-sc-zHs" eventType="editingChanged" id="0KD-Yx-Cl0"/>
                                                        </connections>
                                                    </textField>
                                                </subviews>
                                                <constraints>
                                                    <constraint firstItem="O1l-cp-c2b" firstAttribute="leading" secondItem="pEG-c7-yoZ" secondAttribute="trailing" constant="8" symbolic="YES" id="4bh-3C-WXp"/>
                                                    <constraint firstItem="pEG-c7-yoZ" firstAttribute="centerY" secondItem="O1l-cp-c2b" secondAttribute="centerY" id="A0b-Mk-8KQ"/>
                                                    <constraint firstItem="O1l-cp-c2b" firstAttribute="top" secondItem="AK1-Th-ke8" secondAttribute="topMargin" constant="-2" id="BDA-fk-4JI"/>
                                                    <constraint firstAttribute="trailingMargin" secondItem="O1l-cp-c2b" secondAttribute="trailing" constant="18" id="bYA-UQ-iBv"/>
                                                    <constraint firstItem="pEG-c7-yoZ" firstAttribute="top" secondItem="AK1-Th-ke8" secondAttribute="topMargin" constant="3" id="eDx-qb-b2G"/>
                                                    <constraint firstItem="pEG-c7-yoZ" firstAttribute="leading" secondItem="AK1-Th-ke8" secondAttribute="leadingMargin" id="tpb-h3-LVs"/>
                                                    <constraint firstItem="pEG-c7-yoZ" firstAttribute="centerY" secondItem="AK1-Th-ke8" secondAttribute="centerY" id="vsl-oj-yAN"/>
                                                </constraints>
                                            </tableViewCellContentView>
                                            <connections>
                                                <outlet property="descriptionLabel" destination="pEG-c7-yoZ" id="qdF-mm-xgu"/>
                                                <outlet property="textField" destination="O1l-cp-c2b" id="WMb-QW-wLg"/>
                                            </connections>
                                        </tableViewCell>
                                    </prototypes>
                                </tableView>
                            </subviews>
                            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                            <constraints>
                                <constraint firstItem="2cP-ct-Jtg" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="8M7-lY-IPn"/>
                                <constraint firstItem="2cP-ct-Jtg" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="GaT-6q-zdl"/>
                                <constraint firstAttribute="trailing" secondItem="2cP-ct-Jtg" secondAttribute="trailing" id="pSM-zU-ndL"/>
                                <constraint firstItem="2cP-ct-Jtg" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="tkS-4A-t2B"/>
                            </constraints>
                        </view>
                        <connections>
                            <outlet property="tableView" destination="2cP-ct-Jtg" id="VSj-8p-8c0"/>
                        </connections>
                    </viewController>
                    <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
                </objects>
                <point key="canvasLocation" x="-79.200000000000003" y="138.98050974512745"/>
            </scene>
        </scenes>
    </document>
    

    结果

    enter image description here

    enter image description here

  • 16

    我遇到了同样的问题 . 似乎设置 cell.textlabel.text 属性会将UILabel带到单元格的contentView的前面 . 设置 textLabel.text 后添加textView,或者(如果不可能)调用:

    [cell.contentView bringSubviewToFront:textField]
    
  • 4

    我真的很难在iPad上完成这项任务,文本字段在UITableView中显示为不可见,整个行在获得焦点时变为蓝色 .

    最终对我有用的是Apple的Table View Programming Guide中描述的技术"The Technique for Static Row Content" . 我将标签和textField放在视图的NIB中的UITableViewCell中,然后通过 cellForRowAtIndexPath: 中的插座拉出该单元格 . 生成的代码比UICatalog更整洁 .

  • 0

    以下是我认为正确的方式 . 当我测试它时,它适用于Ipad和Iphone . 我们必须通过对uitableviewcell进行分类来创建我们自己的customCells:

    从interfaceBuilder开始...创建一个新的UIViewcontroller调用它customCell(志愿者为你的那里的xib)确保customCell是uitableviewcell的子类

    现在擦除所有视图并创建一个视图使其成为单个单元格的大小 . 使该视图子类为customcell . 现在创建另外两个视图(复制第一个) .
    转到您的连接检查器,找到2个IBOutlet,您现在可以连接到这些视图 .

    -backgroundView -SelectedBackground

    将这些连接到您刚刚复制的最后两个视图,不要担心它们 . 第一个扩展customCell的视图,将你的标签和uitextfield放在其中 . 进入customCell.h并连接你的标签和文本域 . 将此视图的高度设置为75(所有单元格的高度)全部完成 .

    在customCell.m文件中,确保构造函数看起来像这样:

    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"CustomCell"       owner:self options:nil]; 
        self = [nibArray objectAtIndex:0];
    }
    return self;
    }
    

    现在创建一个UITableViewcontroller,在这个方法中使用customCell类,如下所示:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    static NSString *CellIdentifier = @"Cell";
    // lets use our customCell which has a label and textfield already installed for us
    
    customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        //cell = [[[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    
    
        NSArray *topLevelsObjects = [[NSBundle mainBundle] loadNibNamed:@"NewUserCustomCell" owner:nil options:nil];
        for (id currentObject in topLevelsObjects){
            if ([currentObject  isKindOfClass:[UITableViewCell class]]){
                cell = (customCell *) currentObject;
                break;
            }
        }
    
        NSUInteger row = [indexPath row];
    
    switch (row) {
        case 0:
        {
    
            cell.titleLabel.text = @"First Name"; //label we made (uitextfield also available now)
    
            break;
        }
    
    
            }
    return cell;
    

    }

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    return 75.0;
    }
    
  • 1

    这是 UITableViewCell 的一个drop-in子类,用可编辑的 UITextField 替换 detailTextLabel (或者在 UITableViewCellStyleDefault 的情况下,替换 textLabel ) . 这样做的好处是它允许您重复使用所有熟悉的UITableViewCellStyles,accessoryViews等,现在细节是可编辑的!

    @interface GSBEditableTableViewCell : UITableViewCell <UITextFieldDelegate>
    @property UITextField *textField;
    @end
    
    @interface GSBEditableTableViewCell ()
    @property UILabel *replace;
    @end
    
    @implementation GSBEditableTableViewCell
    
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            _replace = (style == UITableViewCellStyleDefault)? self.textLabel : self.detailTextLabel;
            _replace.hidden = YES;
    
            // Impersonate UILabel with an identical UITextField
            _textField = UITextField.new;
            [self.contentView addSubview:_textField];
            _textField.translatesAutoresizingMaskIntoConstraints = NO;
            [_textField.leftAnchor constraintEqualToAnchor:_replace.leftAnchor].active = YES;
            [_textField.rightAnchor constraintEqualToAnchor:_replace.rightAnchor].active = YES;
            [_textField.topAnchor constraintEqualToAnchor:_replace.topAnchor].active = YES;
            [_textField.bottomAnchor constraintEqualToAnchor:_replace.bottomAnchor].active = YES;
            _textField.font = _replace.font;
            _textField.textColor = _replace.textColor;
            _textField.textAlignment = _replace.textAlignment;
    
            // Dont want to intercept UITextFieldDelegate, so use UITextFieldTextDidChangeNotification instead
            [NSNotificationCenter.defaultCenter addObserver:self
                                               selector:@selector(textDidChange:)
                                                   name:UITextFieldTextDidChangeNotification
                                                 object:_textField];
    
            // Also need KVO because UITextFieldTextDidChangeNotification not fired when change programmatically
            [_textField addObserver:self forKeyPath:@"text" options:0 context:nil];
        }
        return self;
    }
    
    - (void)textDidChange:(NSNotification*)notification
    {
        // Update (hidden) UILabel to ensure correct layout
        if (_textField.text.length) {
            _replace.text = _textField.text;
        } else if (_textField.placeholder.length) {
            _replace.text = _textField.placeholder;
        } else {
            _replace.text = @" "; // otherwise UILabel removed from cell (!?)
        }
        [self setNeedsLayout];
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if ((object == _textField) && [keyPath isEqualToString:@"text"]) [self textDidChange:nil];
    }
    
    - (void)dealloc
    {
        [_textField removeObserver:self forKeyPath:@"text"];
    }
    
    @end
    

    简单易用 - 只需像以前一样创建您的单元格,但现在使用 cell.textField 而不是 cell.detailTextLabel (如果是 UITableViewCellStyleDefault 则使用 cell.textLabel ) . 例如

    GSBEditableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (!cell) cell = [GSBEditableTableViewCell.alloc initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:@"Cell"];
    
    cell.textLabel.text = @"Name";
    cell.textField.text = _editablename;
    cell.textField.delegate = self; // to pickup edits
    ...
    

    FD的答案启发并改进了它

  • 14

    对于UITableViewCell内的多个UITextfield上的下一个/返回事件,我在故事板中使用了UITextField .

    @interface MyViewController () {
        NSInteger currentTxtRow;
    }
    @end
    @property (strong, nonatomic) NSIndexPath   *currentIndex;//Current Selected Row
    
    @implementation MyViewController
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
            UITextField *txtDetails = (UITextField *)[cell.contentView viewWithTag:100];
            txtDetails.delegate = self;
    
            txtDetails.placeholder = self.arrReciversDetails[indexPath.row];
            return cell;
    }
    
    
    #pragma mark - UITextFieldDelegate
    - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    
        CGPoint point = [textField convertPoint:CGPointZero toView:self.tableView];
        self.currentIndex = [self.tableView indexPathForRowAtPoint:point];//Get Current UITableView row
        currentTxtRow = self.currentIndex.row;
        return YES;
    }
    
    
    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
        currentTxtRow += 1;
        self.currentIndex = [NSIndexPath indexPathForRow:currentTxtRow inSection:0];
    
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.currentIndex];
        UITextField *currentTxtfield = (UITextField *)[cell.contentView viewWithTag:100];
        if (currentTxtRow < 3) {//Currently I have 3 Cells each cell have 1 UITextfield
            [currentTxtfield becomeFirstResponder];
        } else {
            [self.view endEditing:YES];
            [currentTxtfield resignFirstResponder];
        }
    
    }
    

    要从文本字段中获取文本 -

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
          switch (self.currentIndex.row) {
    
                case 0:
                    NSLog(@"%@",[NSString stringWithFormat:@"%@%@",textField.text,string]);//Take current word and previous text from textfield
                    break;
    
                case 1:
                     NSLog(@"%@",[NSString stringWithFormat:@"%@%@",textField.text,string]);//Take current word and previous text from textfield
                    break;
    
                case 2:
                     NSLog(@"%@",[NSString stringWithFormat:@"%@%@",textField.text,string]);//Take current word and previous text from textfield
                    break;
    
                default:
                    break;
            }
    }
    

相关问题