如何跟踪来自 viewcontroller 的表格视图单元格文本字段文本?
How to track tableview cell's textfield text from viewcontroller?
我想从相关视图控制器观察 tableview-cell-textfield 文本的变化。
我在单元格内有一个文本字段。它符合名为 'RouteChangesInfoTableViewCellDelegate'
的协议
@protocol RouteChangesInfoTableViewCellDelegate <NSObject>
@required
- (void)textFieldDidChange:(NSString *)textNote;
@end
相关单元格符合该协议。
@interface RouteChangesInfoTableViewCell : UITableViewCell <RouteChangesInfoTableViewCellDelegate>
在 cell 的协议函数内部,我在不调用的情况下委托相关文本。
- (void)textFieldDidChange:(nonnull NSString *)textNote {
[_routeChangesInfoDelegate textFieldDidChange:self.txtNote.text];
}
相关viewcontroller也符合协议
@interface RouteChangesInfoViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, RouteChangesInfoTableViewCellDelegate
在 viewcontroller 内部,我正在尝试如下委托
- (UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
RouteChangesInfoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RouteChangesInfoTableViewCell" forIndexPath:indexPath];
[cell setRouteChangesInfoDelegate:self];
return cell;
}
在 viewcontroller 内部,我正在尝试记录文本,但没有任何反应。
- (void)textFieldDidChange:(nonnull NSString *)textNote {
NSLog(@"DEBUG %@:", textNote);
}
- 这个委托模式对吗?
- 如果我想观察相关文本的变化,我该如何实现观察者(到哪里)
谢谢!
您还没有完全理解 protocol/delegate 模式。
您正确定义协议:
@protocol RouteChangesInfoTableViewCellDelegate <NSObject>
@required
- (void)textFieldDidChange:(NSString *)textNote;
@end
但是您正在设置您的 cell class 以符合该委托。这不是你想要的。
您需要在单元格 class 中创建一个代表 属性。您的 View Controller 将符合该委托,然后将单元格的委托 属性 设置为自身(VC)。
然后将单元格 class 中的 - (IBAction)textFieldDidChange:(id)sender
连接到文本字段。触发时,那个就是你调用委托方法的地方。
这是一个完整的例子...
RouteChangesInfoTableViewCell.h
//
// RouteChangesInfoTableViewCell.h
// Created by Don Mag on 8/29/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RouteChangesInfoTableViewCellDelegate <NSObject>
@required
- (void)textFieldDidChange:(NSString *)textNote;
@end
@interface RouteChangesInfoTableViewCell : UITableViewCell
@property (nonatomic, weak) id <RouteChangesInfoTableViewCellDelegate> routeChangesInfoDelegate;
@end
NS_ASSUME_NONNULL_END
RouteChangesInfoTableViewCell.m
//
// RouteChangesInfoTableViewCell.m
// Created by Don Mag on 8/29/20.
//
#import "RouteChangesInfoTableViewCell.h"
@implementation RouteChangesInfoTableViewCell
- (IBAction)textFieldDidChange:(id)sender {
UITextField *tf = (UITextField *)sender;
[_routeChangesInfoDelegate textFieldDidChange:tf.text];
}
@end
RouteChangesInfoViewController.h
//
// RouteChangesInfoViewController.h
// Created by Don Mag on 8/29/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RouteChangesInfoViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@end
NS_ASSUME_NONNULL_END
RouteChangesInfoViewController.m
//
// RouteChangesInfoViewController.m
// Created by Don Mag on 8/29/20.
//
#import "RouteChangesInfoViewController.h"
#import "RouteChangesInfoTableViewCell.h"
// conform to RouteChangesInfoTableViewCellDelegate
@interface RouteChangesInfoViewController () <RouteChangesInfoTableViewCellDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation RouteChangesInfoViewController
// delegate method
- (void)textFieldDidChange:(NSString *)textNote {
NSLog(@"Got text from cell: %@", textNote);
}
- (void)viewDidLoad {
[super viewDidLoad];
// make sure table view delegate and datasource are set
_tableView.delegate = self;
_tableView.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RouteChangesInfoTableViewCell *cell = (RouteChangesInfoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
// set the cell's delegate
cell.routeChangesInfoDelegate = self;
return cell;
}
@end
带有出口连接的故事板...
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="DgD-su-IwN">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Route Changes Info View Controller-->
<scene sceneID="MLL-TB-u9m">
<objects>
<viewController id="DgD-su-IwN" customClass="RouteChangesInfoViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="rmO-xF-6kM">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Eu3-I2-qTf">
<rect key="frame" x="20" y="144" width="374" height="618"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" id="Wqk-Wo-4g3" customClass="RouteChangesInfoTableViewCell">
<rect key="frame" x="0.0" y="28" width="374" height="50.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Wqk-Wo-4g3" id="kNv-M7-XGt">
<rect key="frame" x="0.0" y="0.0" width="374" height="50.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="pwd-WX-JE1">
<rect key="frame" x="8" y="8" width="358" height="34.5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="textFieldDidChange:" destination="Wqk-Wo-4g3" eventType="editingChanged" id="oUL-ZP-fB5"/>
</connections>
</textField>
</subviews>
<constraints>
<constraint firstItem="pwd-WX-JE1" firstAttribute="top" secondItem="kNv-M7-XGt" secondAttribute="top" constant="8" id="75C-nB-52g"/>
<constraint firstItem="pwd-WX-JE1" firstAttribute="leading" secondItem="kNv-M7-XGt" secondAttribute="leading" constant="8" id="OfP-n0-Ttr"/>
<constraint firstAttribute="bottom" secondItem="pwd-WX-JE1" secondAttribute="bottom" constant="8" id="sqW-Bc-t50"/>
<constraint firstAttribute="trailing" secondItem="pwd-WX-JE1" secondAttribute="trailing" constant="8" id="zrN-ym-Iqw"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="2jf-HS-9oh" firstAttribute="bottom" secondItem="Eu3-I2-qTf" secondAttribute="bottom" constant="100" id="GOH-XI-LDv"/>
<constraint firstItem="2jf-HS-9oh" firstAttribute="trailing" secondItem="Eu3-I2-qTf" secondAttribute="trailing" constant="20" id="W5X-K6-LdN"/>
<constraint firstItem="Eu3-I2-qTf" firstAttribute="leading" secondItem="2jf-HS-9oh" secondAttribute="leading" constant="20" id="a01-1Z-vDi"/>
<constraint firstItem="Eu3-I2-qTf" firstAttribute="top" secondItem="2jf-HS-9oh" secondAttribute="top" constant="100" id="b8m-bN-DQ0"/>
</constraints>
<viewLayoutGuide key="safeArea" id="2jf-HS-9oh"/>
</view>
<connections>
<outlet property="tableView" destination="Eu3-I2-qTf" id="MTy-6L-CMb"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="wqw-h7-jEl" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="150" y="2259"/>
</scene>
</scenes>
</document>
我想从相关视图控制器观察 tableview-cell-textfield 文本的变化。
我在单元格内有一个文本字段。它符合名为 'RouteChangesInfoTableViewCellDelegate'
的协议@protocol RouteChangesInfoTableViewCellDelegate <NSObject>
@required
- (void)textFieldDidChange:(NSString *)textNote;
@end
相关单元格符合该协议。
@interface RouteChangesInfoTableViewCell : UITableViewCell <RouteChangesInfoTableViewCellDelegate>
在 cell 的协议函数内部,我在不调用的情况下委托相关文本。
- (void)textFieldDidChange:(nonnull NSString *)textNote {
[_routeChangesInfoDelegate textFieldDidChange:self.txtNote.text];
}
相关viewcontroller也符合协议
@interface RouteChangesInfoViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, RouteChangesInfoTableViewCellDelegate
在 viewcontroller 内部,我正在尝试如下委托
- (UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
RouteChangesInfoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RouteChangesInfoTableViewCell" forIndexPath:indexPath];
[cell setRouteChangesInfoDelegate:self];
return cell;
}
在 viewcontroller 内部,我正在尝试记录文本,但没有任何反应。
- (void)textFieldDidChange:(nonnull NSString *)textNote {
NSLog(@"DEBUG %@:", textNote);
}
- 这个委托模式对吗?
- 如果我想观察相关文本的变化,我该如何实现观察者(到哪里)
谢谢!
您还没有完全理解 protocol/delegate 模式。
您正确定义协议:
@protocol RouteChangesInfoTableViewCellDelegate <NSObject>
@required
- (void)textFieldDidChange:(NSString *)textNote;
@end
但是您正在设置您的 cell class 以符合该委托。这不是你想要的。
您需要在单元格 class 中创建一个代表 属性。您的 View Controller 将符合该委托,然后将单元格的委托 属性 设置为自身(VC)。
然后将单元格 class 中的 - (IBAction)textFieldDidChange:(id)sender
连接到文本字段。触发时,那个就是你调用委托方法的地方。
这是一个完整的例子...
RouteChangesInfoTableViewCell.h
//
// RouteChangesInfoTableViewCell.h
// Created by Don Mag on 8/29/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RouteChangesInfoTableViewCellDelegate <NSObject>
@required
- (void)textFieldDidChange:(NSString *)textNote;
@end
@interface RouteChangesInfoTableViewCell : UITableViewCell
@property (nonatomic, weak) id <RouteChangesInfoTableViewCellDelegate> routeChangesInfoDelegate;
@end
NS_ASSUME_NONNULL_END
RouteChangesInfoTableViewCell.m
//
// RouteChangesInfoTableViewCell.m
// Created by Don Mag on 8/29/20.
//
#import "RouteChangesInfoTableViewCell.h"
@implementation RouteChangesInfoTableViewCell
- (IBAction)textFieldDidChange:(id)sender {
UITextField *tf = (UITextField *)sender;
[_routeChangesInfoDelegate textFieldDidChange:tf.text];
}
@end
RouteChangesInfoViewController.h
//
// RouteChangesInfoViewController.h
// Created by Don Mag on 8/29/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RouteChangesInfoViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@end
NS_ASSUME_NONNULL_END
RouteChangesInfoViewController.m
//
// RouteChangesInfoViewController.m
// Created by Don Mag on 8/29/20.
//
#import "RouteChangesInfoViewController.h"
#import "RouteChangesInfoTableViewCell.h"
// conform to RouteChangesInfoTableViewCellDelegate
@interface RouteChangesInfoViewController () <RouteChangesInfoTableViewCellDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation RouteChangesInfoViewController
// delegate method
- (void)textFieldDidChange:(NSString *)textNote {
NSLog(@"Got text from cell: %@", textNote);
}
- (void)viewDidLoad {
[super viewDidLoad];
// make sure table view delegate and datasource are set
_tableView.delegate = self;
_tableView.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RouteChangesInfoTableViewCell *cell = (RouteChangesInfoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
// set the cell's delegate
cell.routeChangesInfoDelegate = self;
return cell;
}
@end
带有出口连接的故事板...
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="DgD-su-IwN">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Route Changes Info View Controller-->
<scene sceneID="MLL-TB-u9m">
<objects>
<viewController id="DgD-su-IwN" customClass="RouteChangesInfoViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="rmO-xF-6kM">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Eu3-I2-qTf">
<rect key="frame" x="20" y="144" width="374" height="618"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" id="Wqk-Wo-4g3" customClass="RouteChangesInfoTableViewCell">
<rect key="frame" x="0.0" y="28" width="374" height="50.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Wqk-Wo-4g3" id="kNv-M7-XGt">
<rect key="frame" x="0.0" y="0.0" width="374" height="50.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="pwd-WX-JE1">
<rect key="frame" x="8" y="8" width="358" height="34.5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="textFieldDidChange:" destination="Wqk-Wo-4g3" eventType="editingChanged" id="oUL-ZP-fB5"/>
</connections>
</textField>
</subviews>
<constraints>
<constraint firstItem="pwd-WX-JE1" firstAttribute="top" secondItem="kNv-M7-XGt" secondAttribute="top" constant="8" id="75C-nB-52g"/>
<constraint firstItem="pwd-WX-JE1" firstAttribute="leading" secondItem="kNv-M7-XGt" secondAttribute="leading" constant="8" id="OfP-n0-Ttr"/>
<constraint firstAttribute="bottom" secondItem="pwd-WX-JE1" secondAttribute="bottom" constant="8" id="sqW-Bc-t50"/>
<constraint firstAttribute="trailing" secondItem="pwd-WX-JE1" secondAttribute="trailing" constant="8" id="zrN-ym-Iqw"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="2jf-HS-9oh" firstAttribute="bottom" secondItem="Eu3-I2-qTf" secondAttribute="bottom" constant="100" id="GOH-XI-LDv"/>
<constraint firstItem="2jf-HS-9oh" firstAttribute="trailing" secondItem="Eu3-I2-qTf" secondAttribute="trailing" constant="20" id="W5X-K6-LdN"/>
<constraint firstItem="Eu3-I2-qTf" firstAttribute="leading" secondItem="2jf-HS-9oh" secondAttribute="leading" constant="20" id="a01-1Z-vDi"/>
<constraint firstItem="Eu3-I2-qTf" firstAttribute="top" secondItem="2jf-HS-9oh" secondAttribute="top" constant="100" id="b8m-bN-DQ0"/>
</constraints>
<viewLayoutGuide key="safeArea" id="2jf-HS-9oh"/>
</view>
<connections>
<outlet property="tableView" destination="Eu3-I2-qTf" id="MTy-6L-CMb"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="wqw-h7-jEl" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="150" y="2259"/>
</scene>
</scenes>
</document>