In WWDC 2013-Video schlägt Apple vor, die Auswahl in einer Tabellenansicht in iOS 7 anzuzeigen. Wie wird eine Ansicht zwischen Zellen der Tabellenansicht eingefügt und animiert?
So aus der Apple Kalender-App:
In WWDC 2013-Video schlägt Apple vor, die Auswahl in einer Tabellenansicht in iOS 7 anzuzeigen. Wie wird eine Ansicht zwischen Zellen der Tabellenansicht eingefügt und animiert?
So aus der Apple Kalender-App:
Antworten:
Mit iOS7 hat Apple den Beispielcode veröffentlicht DateCell
.
Demonstriert die formatierte Anzeige von Datumsobjekten in Tabellenzellen und die Verwendung von UIDatePicker zum Bearbeiten dieser Werte. Als Delegat dieser Tabelle verwendet das Beispiel die Methode "didSelectRowAtIndexPath", um das UIDatePicker-Steuerelement zu öffnen.
Für iOS 6.x und frühere Versionen wird UIViewAnimation verwendet, um den UIDatePicker auf dem Bildschirm nach oben und außerhalb des Bildschirms nach unten zu schieben. Für iOS 7.x wird der UIDatePicker der Tabellenansicht inline hinzugefügt.
Die Aktionsmethode des UIDatePicker legt die NSDate-Eigenschaft der benutzerdefinierten Tabellenzelle direkt fest. Darüber hinaus zeigt dieses Beispiel, wie die NSDateFormatter-Klasse verwendet wird, um das datumsformatierte Erscheinungsbild der benutzerdefinierten Zelle zu erzielen.
Sie können den Beispielcode hier herunterladen: DateCell .
Sie können die Antwort verwenden, die ich zuvor unten gegeben habe, oder diese neue Klasse in Swift verwenden, die ich erstellt habe, um diese Aufgabe viel einfacher und sauberer zu gestalten: https://github.com/AaronBratcher/TableViewHelper
Ich finde den von Apple bereitgestellten Code in vielerlei Hinsicht problematisch:
Bei statischen Zelltabellen definiere ich meine Datumsauswahlzelle unter meiner Datumsanzeigezelle und habe ein Flag, das angibt, ob ich sie bearbeite. Wenn ja, gebe ich eine angemessene Zellenhöhe zurück, andernfalls gebe ich eine Zellenhöhe von Null zurück.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && indexPath.row == 2) { // this is my picker cell
if (editingStartTime) {
return 219;
} else {
return 0;
}
} else {
return self.tableView.rowHeight;
}
}
Wenn auf die Zeile mit dem Datum geklickt wird, ändere ich das Flag und führe die Aktualisierungsanimation durch, um die Auswahl anzuzeigen.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && indexPath.row == 1) { // this is my date cell above the picker cell
editingStartTime = !editingStartTime;
[UIView animateWithDuration:.4 animations:^{
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:2 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView reloadData];
}];
}
}
Wenn ich mehrere Datums- / Zeitauswahlelemente in derselben Tabelle habe, setze ich die Flags beim Klicken entsprechend und lade die entsprechenden Zeilen neu. Ich habe festgestellt, dass ich meine statische Tabelle behalten, viel weniger Code verwenden und leichter verstehen kann, was passiert.
Mit dem Storyboard und einer statischen Tabelle konnte ich mit dem folgenden Code das gleiche Ergebnis erzielen. Dies ist eine großartige Lösung, denn wenn Sie viele ungewöhnlich geformte Zellen haben oder mehrere Zellen haben möchten, die dynamisch angezeigt / ausgeblendet werden, funktioniert dieser Code weiterhin.
@interface StaticTableViewController: UITableViewController
@property (weak, nonatomic) IBOutlet UITableViewCell *dateTitleCell; // cell that will open the date picker. This is linked from the story board
@property (nonatomic, assign, getter = isDateOpen) BOOL dateOpen;
@end
@implementation StaticTableViewController
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
// This is the index path of the date picker cell in the static table
if (indexPath.section == 1 && indexPath.row == 1 && !self.isDateOpen){
return 0;
}
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
[tableView beginUpdates];
if (cell == self.dateTitleCell){
self.dateOpen = !self.isDateOpen;
}
[tableView reloadData];
[self.tableView endUpdates];
}
[tableView reloadData];
Anruf ist nicht erforderlich. Derzeit deaktiviert es die Zeilenauswahl, aber es ist besser, die Auswahl der Zeile wie [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
Ich habe die DateCell-Quelle von Apple übernommen und die Storyboard-Datei entfernt.
Wenn Sie eines ohne Storyboard wünschen, schauen Sie unter: https://github.com/ajaygautam/DateCellWithoutStoryboard
UIDatePicker
mit UIPickerView
. Ich habe einige Dinge ausprobiert und konnte sie pickerView
auf jeder Zelle anzeigen, aber sie wird nicht mit jeder Zelle aktualisiert. Ich habe meine Frage und meinen Code hier gepostet . Bitte schauen Sie mal rein und es wäre sehr nett, wenn Sie mir eine Lösung vorschlagen könnten.
UIDatePicker
mit UIPickerView
aber mit paar Bugs. 1. Es stürzt ab, wenn Sie UIPickerView
die Tabelle öffnen und scrollen. 2. Der Wert wird automatisch UILabel
Detail in den unteren Zeilen der Tabelle zugewiesen, wenn Werte der Beschriftung Details in den oberen Zeilen zugewiesen werden. Hier ist mein Code
Eines der besten Tutorials dazu ist iOS 7 Inline UIDatePicker - Teil 2 . Grundsätzlich verwende ich hier statische Tabellenansichtszellen und implementiere einige zusätzliche Methoden. Ich habe dafür Xamarin und C # verwendet:
Du musst aktiv sein Clip Subviews
.
Höhe einstellen:
public override float GetHeightForRow (UITableView tableView, NSIndexPath indexPath)
{
if (indexPath.Row == 4) {
return (datePickerIsShowing) ? 206f : 0.0f;
}
return base.GetHeightForRow(tableView,indexPath);
}
Als eine Klassenvariable: private bool datePickerIsShowing = false;
Datumsauswahl anzeigen:
private void showDatePickerCell(){
datePickerIsShowing = true;
this.TableView.BeginUpdates ();
this.TableView.EndUpdates ();
this.datePicker.Hidden = false;
this.datePicker.Alpha = 0.0f;
UIView.Animate (0.25, animation:
() => {
this.datePicker.Alpha = 1.0f;
}
);
}
Datumsauswahl ausblenden:
private void hideDatePickerCell(){
datePickerIsShowing = false;
this.TableView.BeginUpdates ();
this.TableView.EndUpdates ();
UIView.Animate (0.25,
animation: () => {
this.datePicker.Alpha = 0.0f;
},
completion: () => {
this.datePicker.Hidden = true;
}
);
}
Und diese Funktionen aufrufen:
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
if (indexPath.Row == 3) {
if (datePickerIsShowing) {
hideDatePickerCell ();
} else {
showDatePickerCell ();
}
}
this.TableView.DeselectRow (indexPath, true);
}
Ich habe meinen eigenen benutzerdefinierten Ansichts-Controller erstellt, um das Hinzufügen einer Inline-Auswahl in einer Tabellenansicht zu vereinfachen. Sie unterteilen es einfach und befolgen einige einfache Regeln. Es behandelt die Präsentation der Datumsauswahl.
Sie finden es hier zusammen mit einem Beispielprojekt, das die Verwendung demonstriert: https://github.com/ale84/ALEInlineDatePickerViewController
Ich habe eine Antwort auf einen Fehler im Beispiel für die Datumszelle von Apple gefunden, bei dem eine Zeile unter der letzten Datumszelle stehen muss, sonst wird eine Fehlermeldung angezeigt. In der CellForRowAtIndexPath-Methode ersetzen Sie die ItemData-Zeile durch
NSArray *itemsArray = [self.dataArray objectAtIndex:indexPath.section];
NSDictionary *itemData = nil;
if(![indexPath isEqual:self.datePickerIndexPath])
itemData = [itemsArray objectAtIndex:modelRow];
Nach dem Ersetzen des Beispielcodes kann ich jetzt eine datePicker-Zelle anzeigen, ohne dass sich eine Zelle darunter befindet.
Ich bin gerade zu stackoverflow gekommen. Wenn dies also am falschen Ort oder woanders ist, entschuldige ich mich.
Die Antwort von Aaron Bratcher funktionierte nur in mehreren Abschnitten. Die Animationen waren etwas abgehackt und die nächsten Abschnitte liefen nicht sehr gut nach unten. Um dies zu beheben, habe ich die nächsten Abschnitte durchlaufen und die Zeilen um den gleichen Betrag wie die Höhe der Datumsauswahl nach unten verschoben.
Ich habe den didSelectRowAtIndexPath wie folgt bearbeitet:
// Return Data to delegate: either way is fine, although passing back the object may be more efficient
// [_delegate imageSelected:currentRecord.image withTitle:currentRecord.title withCreator:currentRecord.creator];
// [_delegate animalSelected:currentRecord];
if (indexPath.section == 1 && indexPath.row == 0) { // this is my date cell above the picker cell
editingStartTime = !editingStartTime;
[UIView animateWithDuration:.4 animations:^{
int height = 0;
if (editingStartTime) {
height = 162;
}
UITableViewCell* temp = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
[temp setFrame:CGRectMake(temp.frame.origin.x, temp.frame.origin.y, temp.frame.size.width, height)];
for (int x = 2; x < [tableView numberOfSections]; x++) {
for (int y = 0; y < [tableView numberOfRowsInSection:x]; y++) {
UITableViewCell* temp = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:y inSection:x]];
int y_coord = temp.frame.origin.y-162;
if (editingStartTime) {
y_coord = temp.frame.origin.y+162;
}
[temp setFrame:CGRectMake(temp.frame.origin.x, y_coord, temp.frame.size.width, temp.frame.size.height)];
}
}
}completion:^(BOOL finished){
[self.tableView reloadData];
}];
}
Hinzufügen zu den vorherigen Antworten,
Ich habe sowohl @datinc- als auch @Aaron Bratcher-Lösungen ausprobiert. Beide haben hervorragend funktioniert, aber die Animation war in einer gruppierten statischen Tabellenansicht nicht so sauber.
Nachdem ich ein bisschen damit gespielt hatte, kam ich zu diesem Code, der sauber und großartig für mich funktioniert -
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && indexPath.row == 1)
{
if (self.isPickerOpened)
{
return 162;
}
else
{
return 0;
}
}
else
{
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 0) {
[tableView beginUpdates];
self.isPickerOpened = ! self.isPickerOpened;
[super tableView:tableView heightForRowAtIndexPath:indexPath];
[self.tableView endUpdates];
}
}
Die Hauptänderung ist zu verwenden -
[super tableView:tableView heightForRowAtIndexPath:indexPath];
Um die Zeile zu aktualisieren, werden auf diese Weise die restlichen Tabellenabschnitte und Zellen nicht animiert.
Hoffe es hilft jemandem.
Shani
Hinzufügen zu den vorherigen Antworten und @ Aaron Bratcher-Lösung ...
Seit iOS 9 bekam ich abgehackte Animationen, und das Laden der Tabelle dauerte eine Weile und war nervig genug. Ich habe es auf die Datumsauswahl beschränkt, die nur langsam vom Storyboard geladen wird. Das programmgesteuerte Hinzufügen der Picker anstelle des Storyboards verbesserte die Ladeleistung, und als Nebenprodukt ist die Animation flüssiger.
Entfernen Sie die Datumsauswahl aus dem Storyboard und haben Sie eine leere Zelle, in der Sie die Höhe wie in den vorherigen Antworten festlegen. Rufen Sie dann eine Initialisierung für viewDidLoad auf:
- (void)initialiseDatePickers
{
self.isEditingStartTime = NO;
self.startTimePickerCell.clipsToBounds = YES;
UIDatePicker *startTimePicker = [[UIDatePicker alloc] init];
[startTimePicker addTarget:self action:@selector(startTimePickerChanged:) forControlEvents:UIControlEventValueChanged];
[self.startTimePickerCell addSubview:startTimePicker];
}
Dann implementieren Sie die Aktion zB
- (IBAction)startTimePickerChanged:(id)sender
{
NSLog(@"start time picker changed");
}
Dadurch wird die Tabelle viel schneller als zuvor geladen. Sie entfernen auch die Animationslinie aus, didSelectRowAtIndexPath
da sie ohne sie reibungslos animiert (ymmv).
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && indexPath.row == 1) { // this is my date cell above the picker cell
editingStartTime = !editingStartTime;
}
}
Die Verwendung dieser Antwort ohne Animation funktioniert in iOS 8.1 ordnungsgemäß. Ich habe es unten in Swift umgewandelt:
import UIKit
class TableViewController: UITableViewController {
var editingCell: Bool = false
@IBOutlet weak var myCell: UITableViewCell!
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// Change the section and row to the title cell the user taps to reveal
// the cell below
if (indexPath.section == 0 && indexPath.row == 2 && !editingCell) {
return 0
} else {
return self.tableView.rowHeight
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.deselectRowAtIndexPath(indexPath, animated: false);
var cell = tableView.cellForRowAtIndexPath(indexPath)
self.tableView.beginUpdates()
if (cell == self.myCell) {
editingType = !editingType;
}
self.tableView.endUpdates()
}
}
Hier ist eine andere Möglichkeit, das Problem ohne statische konstante Zahlen zu lösen. Alle Zellen können in statischen und dynamischen Tabellenansichten verwendet werden. Diese Methode verwendet eine einzelne Zelle sowohl für die Titel- als auch für die Datumsauswahl!
Übrigens können Sie so viele Dattelwähler in Ihrem Tisch haben, wie Sie möchten!
Erstellen Sie eine UITableViewCell- Unterklasse:
Alle Ihre Tabellenansichtszellen müssen von dieser Klasse geerbt werden und Sie müssen die Zellenhöhe für jede Zeile manuell festlegen.
//
// CPTableViewCell.h
//
// Copyright (c) CodePigeon. All rights reserved.
//
@class CPTableViewCell;
#define kUIAnimationDuration 0.33f
@protocol CPTableViewCellDelegate <NSObject>
@required
- (void)tableViewCellDidChangeValue:(CPTableViewCell *)cell;
@optional
- (void)tableViewCellDidBecomeFirstResponder:(CPTableViewCell *)cell;
- (void)tableViewCellResignedFirstResponder:(CPTableViewCell *)cell;
@end
@interface CPTableViewCell : UITableViewCell
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet CPTableViewCell *nextCell;
@property (nonatomic, weak) IBOutlet id<CPTableViewCellDelegate> delegate;
@property (nonatomic, copy) IBInspectable NSString *dataBindKey;
@property (nonatomic) IBInspectable CGFloat height;
@property (nonatomic, readonly) BOOL isFirstResponder;
@property (nonatomic) BOOL isEnabled;
- (void)commonInit;
- (id)value;
- (void)setValue:(id)value;
@end
//
// CPTableViewCell.m
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPTableViewCell.h"
@interface CPTableViewCell ()
@end
@implementation CPTableViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self)
return nil;
[self commonInit];
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (!self)
return nil;
[self commonInit];
return self;
}
- (void)commonInit
{
_isFirstResponder = NO;
_isEnabled = YES;
}
- (BOOL)canBecomeFirstResponder
{
return _isEnabled;
}
- (BOOL)becomeFirstResponder
{
if ([_delegate respondsToSelector:@selector(tableViewCellDidBecomeFirstResponder:)])
[_delegate tableViewCellDidBecomeFirstResponder:self];
return _isFirstResponder = YES;
}
- (BOOL)resignFirstResponder
{
if (_isFirstResponder)
{
if ([_delegate respondsToSelector:@selector(tableViewCellResignedFirstResponder:)])
[_delegate tableViewCellResignedFirstResponder:self];
_isFirstResponder = NO;
}
return _isFirstResponder;
}
- (id)value
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
- (void)setValue:(id)value
{
[self doesNotRecognizeSelector:_cmd];
}
@end
Erstellen Sie eine CPDatePickerTableViewCell- Klasse aus unserer CPTableViewCell
//
// CPDatePickerTableViewCell.h
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPTableViewCell.h"
@interface CPDatePickerTableViewCell : CPTableViewCell
@property (nonatomic, copy) IBInspectable NSString *dateFormat;
@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *dateLabel;
@property (nonatomic, weak) IBOutlet UIDatePicker *datePicker;
@end
//
// CPDatePickerTableViewCell.m
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPDatePickerTableViewCell.h"
#define kCPDatePickerTableViewCellPickerHeight 162.f
@interface CPDatePickerTableViewCell () <UITextFieldDelegate, UIPickerViewDelegate>
{
NSDateFormatter *_dateFormatter;
BOOL _isOpen;
}
@end
@implementation CPDatePickerTableViewCell
- (void)awakeFromNib
{
[super awakeFromNib];
_dateFormatter = [NSDateFormatter new];
[_dateFormatter setDateFormat:_dateFormat];
self.selectionStyle = UITableViewCellSelectionStyleNone;
_dateLabel.text = [_dateFormatter stringFromDate:_datePicker.date];
_datePicker.alpha = 0.f;
_isOpen = NO;
}
- (BOOL)becomeFirstResponder
{
if (_isOpen == NO)
{
self.height += kCPDatePickerTableViewCellPickerHeight;
}
else
{
self.height -= kCPDatePickerTableViewCellPickerHeight;
}
[UIView animateWithDuration:kUIAnimationDuration animations:^{
_datePicker.alpha = _isOpen ? 0.0f : 1.0f;
}];
[self.tableView beginUpdates];
[self.tableView endUpdates];
_isOpen = !_isOpen;
[self.tableView endEditing:YES];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
if (_isOpen == YES)
{
self.height -= kCPDatePickerTableViewCellPickerHeight;
[UIView animateWithDuration:kUIAnimationDuration animations:^{
_datePicker.alpha = 0.0f;
}];
[self.tableView beginUpdates];
[self.tableView endUpdates];
_isOpen = NO;
}
return [super resignFirstResponder];
}
- (id)value
{
return _datePicker.date;
}
- (void)setValue:(NSDate *)value
{
_datePicker.date = value;
_dateLabel.text = [_dateFormatter stringFromDate:_datePicker.date];
}
- (IBAction)datePickerValueChanged:(UIDatePicker *)sender
{
[_dateLabel setText:[_dateFormatter stringFromDate:_datePicker.date]];
[self.delegate tableViewCellDidChangeValue:self];
}
@end
Implementieren Sie in Ihrem View Controller diese beiden Delegate-Methoden
#pragma mark - UITableViewDelegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CPTableViewCell *cell = (CPTableViewCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath];
return [cell height];
}
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
CPTableViewCell *cell = (CPTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if ([cell canBecomeFirstResponder])
{
[cell becomeFirstResponder];
}
if (cell != _selectedCell)
{
[_selectedCell resignFirstResponder];
}
_selectedCell = cell;
return YES;
}
Beispiel zum Einrichten von Einschränkungen im Interface Builder
Zusätzlich habe ich benutzerdefinierte Zellklassen für UITextField und UITextView geschrieben, wobei tableView: didSelectRowAtIndexPath: aufgerufen wird, wenn cell ausgewählt ist!
CPTextFieldTableViewCell
//
// CPTextFieldTableViewCell.h
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPTableViewCell.h"
@interface CPTextFieldTableViewCell : CPTableViewCell
@property (nonatomic, weak) IBOutlet UITextField *inputTextField;
@end
//
// CPTextFieldTableViewCell.m
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPTextFieldTableViewCell.h"
@interface CPTextFieldTableViewCell () <UITextFieldDelegate>
@end
@implementation CPTextFieldTableViewCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.selectionStyle = UITableViewCellSelectionStyleNone;
_inputTextField.userInteractionEnabled = NO;
_inputTextField.delegate = self;
}
- (BOOL)becomeFirstResponder
{
_inputTextField.userInteractionEnabled = YES;
[_inputTextField becomeFirstResponder];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
_inputTextField.userInteractionEnabled = NO;
return [super resignFirstResponder];
}
- (void)setIsEnabled:(BOOL)isEnabled
{
[super setIsEnabled:isEnabled];
_inputTextField.enabled = isEnabled;
}
- (id)value
{
return _inputTextField.text;
}
- (void)setValue:(NSString *)value
{
_inputTextField.text = value;
}
#pragma mark - UITextFieldDelegate methods
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self.delegate tableViewCellDidChangeValue:self];
}
@end
CBTextViewTableViewCell
Die Zellenhöhe ist dynamisch und die Zeile wächst, wenn der Text in eine neue Zeile eingeschlossen wird!
//
// CBTextViewTableViewCell.h
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPTableViewCell.h"
@interface CPTextViewTableViewCell : CPTableViewCell
@property (nonatomic, weak) IBOutlet UITextView *inputTextView;
@end
//
// CBTextViewTableViewCell.m
//
// Copyright (c) CodePigeon. All rights reserved.
//
#import "CPTextViewTableViewCell.h"
@interface CPTextViewTableViewCell () <UITextViewDelegate>
{
UITextView *_heightTextView;
}
@end
@implementation CPTextViewTableViewCell
@synthesize height = _height;
- (void)awakeFromNib
{
[super awakeFromNib];
self.selectionStyle = UITableViewCellSelectionStyleNone;
_inputTextView.userInteractionEnabled = NO;
_inputTextView.delegate = self;
_inputTextView.contentInset = UIEdgeInsetsZero;
_inputTextView.scrollEnabled = NO;
}
- (CGFloat)height
{
if (!_heightTextView)
{
CGRect frame = (CGRect) {
.origin = CGPointMake(0.f, 0.f),
.size = CGSizeMake(_inputTextView.textInputView.frame.size.width, 0.f)
};
_heightTextView = [[UITextView alloc] initWithFrame:frame];
_heightTextView.font = [UIFont systemFontOfSize:_inputTextView.font.pointSize];
_heightTextView.textColor = UIColor.whiteColor;
_heightTextView.contentInset = UIEdgeInsetsZero;
}
_heightTextView.text = _inputTextView.text;
CGSize size = [_heightTextView sizeThatFits:CGSizeMake(_inputTextView.textInputView.frame.size.width, FLT_MAX)];
return size.height > _height ? size.height + _inputTextView.font.pointSize : _height;
}
- (BOOL)becomeFirstResponder
{
_inputTextView.userInteractionEnabled = YES;
[_inputTextView becomeFirstResponder];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
_inputTextView.userInteractionEnabled = NO;
return [super resignFirstResponder];
}
- (void)setIsEnabled:(BOOL)isEnabled
{
[super setIsEnabled:isEnabled];
_inputTextView.editable = isEnabled;
}
- (id)value
{
return _inputTextView.text;
}
- (void)setValue:(NSString *)value
{
_inputTextView.text = value;
[_inputTextView setNeedsLayout];
[_inputTextView layoutIfNeeded];
}
#pragma mark - UITextViewDelegate methods
- (void)textViewDidChange:(UITextView *)textView
{
[self.delegate tableViewCellDidChangeValue:self];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
@end
Der einfachste Weg, DateCell in der Swift-Version zu verwenden: Verwenden Sie dieses Beispiel .
Ziehen Sie die Klasse " DateCellTableViewController.swift " in Ihr Projekt.
Öffnen Sie "Main.storyboard" und kopieren Sie das " DateCell " ViewController-Objekt und fügen Sie es in Ihr Storyboard ein.