web-dev-qa-db-fra.com

iOS 7 - Comment afficher un sélecteur de date en place dans une vue de table?

Dans la vidéo WWDC 2013, Apple suggère d’afficher le sélecteur en place dans une vue de tableau sous iOS 7. Comment insérer et animer une vue entre des cellules de vue de tableau?

Comme cela, à partir de l'application de calendrier Apple: 

In-place date picker

118
x.y

Avec iOS7, Apple a publié l'exemple de code DateCell.

enter image description here

Démonstration de l'affichage formaté des objets de date dans les cellules de tableau et de l'utilisation de UIDatePicker pour modifier ces valeurs . En tant que délégué à cette table, l'exemple utilise la méthode "didSelectRowAtIndexPath" pour ouvrir le contrôle UIDatePicker.

Pour iOS 6.x et les versions antérieures, UIViewAnimation est utilisé pour faire glisser UIDatePicker vers le haut à l'écran et le désactiver. Pour iOS 7.x, le UIDatePicker est ajouté en ligne à la vue Table.

La méthode d'action de UIDatePicker définira directement la propriété NSDate de la cellule de tableau personnalisée. En outre, cet exemple montre comment utiliser la classe NSDateFormatter pour obtenir l'apparence formatée en date de la cellule personnalisée.

enter image description here

Vous pouvez télécharger l'exemple de code ici: DateCell .

101
Nitin Gohel

Vous pouvez utiliser la réponse donnée précédemment ci-dessous ou utiliser cette nouvelle classe dans Swift que j’ai fait pour que cette tâche soit lot plus simple et plus propre: https://github.com/AaronBratcher/TableViewHelper


Je trouve le code fourni par Apple problématique de plusieurs manières:

  • Vous ne pouvez pas avoir une table statique car ils utilisent la méthode tableView: cellForRowAtIndexPath
  • Le code se bloque si vous n'avez pas de lignes supplémentaires en dessous de la dernière cellule du sélecteur de date

Pour les tables de cellules statiques, je définis ma cellule de sélection de date sous ma cellule d'affichage de la date et un indicateur identifiant si je la modifie. Si je le suis, je renvoie une hauteur de cellule appropriée, sinon je renvoie une hauteur de cellule de zéro.

- (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;
    }
}

Lorsque la ligne affichant la date est cliquée, je modifie l'indicateur et effectue l'animation de mise à jour pour afficher le sélecteur.

-(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];
        }];
    }
}

Si j'ai plusieurs sélecteurs de date/heure dans la même table, je règle les indicateurs en conséquence sur le clic et recharge les lignes appropriées. J'ai constaté que je pouvais conserver ma table statique, utiliser beaucoup moins de code et il est plus facile de comprendre ce qui se passe.

84
Aaron Bratcher

En utilisant le storyboard et une table statique, j'ai pu obtenir le même résultat en utilisant le code suivant. C'est une excellente solution car si vous avez plusieurs cellules de forme irrégulière ou si vous voulez avoir plusieurs cellules affichées/masquées de manière dynamique, ce code fonctionnera toujours.

@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];
}
18
datinc

J'ai pris le code source DateCell d'Apple et supprimé le fichier de scénario.

Si vous en voulez un sans storyboard, regardez: https://github.com/ajaygautam/DateCellWithoutStoryboard

5
Ajay Gautam

L'un des meilleurs tutoriels à ce sujet est UIDatePicker en ligne iOS 7 - Partie 2 . Fondamentalement, ici, j'utilise des cellules de vue de table statique et implémente des méthodes supplémentaires. J'ai utilisé Xamarin et C # pour cela:

Vous devez activer Clip Subviews.

Réglage de la hauteur:

public override float GetHeightForRow (UITableView tableView, NSIndexPath indexPath)
{
    if (indexPath.Row == 4) {
        return (datePickerIsShowing) ? 206f : 0.0f;
    }

    return base.GetHeightForRow(tableView,indexPath);
}

Qu'une variable de classe: private bool datePickerIsShowing = false;

Afficher le sélecteur de date:

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;
        }
    );
} 

Masquer le sélecteur de date:

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;
        }
    );
} 

Et en appelant cette fonction:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
    if (indexPath.Row == 3) {
        if (datePickerIsShowing) {
            hideDatePickerCell ();
        } else {
            showDatePickerCell ();
        }
    }

    this.TableView.DeselectRow (indexPath, true);
}
5
testing

J'ai créé mon propre contrôleur de vue personnalisé afin de simplifier le processus d'ajout d'un sélecteur en ligne dans une table. Vous venez de le sous-classer et de suivre quelques règles simples et il gère la présentation du sélecteur de date.

Vous pouvez le trouver ici avec un exemple de projet qui montre comment l'utiliser: https://github.com/ale84/ALEInlineDatePickerViewController

3
ale84

J'ai trouvé une réponse à une faille dans l'exemple de cellule de données d'Apple dans lequel vous devez avoir une ligne en dessous de la dernière cellule de données ou vous obtenez une erreur. Dans la méthode CellForRowAtIndexPath, remplacez la ligne ItemData par 

NSArray *itemsArray = [self.dataArray objectAtIndex:indexPath.section];
NSDictionary *itemData = nil;

if(![indexPath isEqual:self.datePickerIndexPath])
    itemData = [itemsArray objectAtIndex:modelRow];

Après avoir remplacé l'exemple de code, je peux maintenant afficher une cellule datePicker sans la placer en dessous.

Je viens de rejoindre stackoverflow, donc si c'est au mauvais endroit ou ailleurs, je m'en excuse.

3
pjmarshall1

Ajout aux réponses précédentes,

J'ai essayé les solutions @datinc et @Aaron Bratcher. Les deux solutions fonctionnaient très bien, mais l'animation n'était pas aussi nette dans un tableau statique groupé.

Après avoir joué un peu, je suis arrivé à ce code qui fonctionne proprement et très bien pour moi -

- (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];
    }
}

Le principal changement consiste à utiliser -

        [super tableView:tableView heightForRowAtIndexPath:indexPath];

pour mettre à jour la ligne, les autres sections du tableau et les cellules ne s'animent pas.

J'espère que ça aide quelqu'un.

Shani

3
shannoga

La réponse d'Aaron Bratcher a fonctionné sauf lorsqu'elle a été utilisée avec plusieurs sections. Les animations étaient un peu saccadées et les sections suivantes ne glissaient pas très bien. Pour résoudre ce problème, j'ai parcouru l'ensemble des sections suivantes et traduit les lignes du même montant que la hauteur du sélecteur de date.

J'ai modifié le didSelectRowAtIndexPath en:

// 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];
    }];
}
3
Timothy Logan

Ajout aux réponses précédentes et à la solution @Aaron Bratcher ...

J'avais des animations saccadées depuis iOS 9, et le chargement de la table prenait un certain temps et c'était assez ennuyant. Je l'ai réduit aux sélecteurs de dates ralentissant le chargement depuis le storyboard. L'ajout des sélecteurs par programmation plutôt que dans le storyboard a amélioré les performances de chargement et, en tant que sous-produit, l'animation est plus fluide. 

Supprimez le sélecteur de date du storyboard et laissez une cellule vide, définissez la hauteur comme dans les réponses précédentes, puis appelez une initialisation sur viewDidLoad:

- (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];
}

Ensuite, implémentez l'action, par exemple.

- (IBAction)startTimePickerChanged:(id)sender
{
    NSLog(@"start time picker changed");
}

Cela charge la table beaucoup plus rapidement que précédemment. Vous supprimez également la ligne d’animation de didSelectRowAtIndexPath car elle s’anime en douceur sans elle (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;
    }
}
2
matt_s

L'utilisation de cette réponse sans l'animation fonctionne correctement sous iOS 8.1. Je l'ai converti en Swift ci-dessous:

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()
    }
}
1
DavidM

Voici un autre moyen de résoudre le problème sans nombres constants statiques. Toutes les cellules peuvent être utilisées dans des vues tabulaires statiques et dynamiques. Cette méthode utilise une seule cellule pour le titre et le sélecteur de date! 

Btw, vous pouvez avoir autant de sélecteurs de date dans votre table que vous le souhaitez!

Créez une sous-classe UITableViewCell:

Toutes les cellules de votre vue tableau doivent être héritées de cette classe et vous devez définir la hauteur de la cellule manuellement pour chaque ligne. 

//
//  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

Créez une classe CPDatePickerTableViewCell à partir de notre 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

Dans votre vue, implémentez ces deux méthodes de délégation

#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;
}

Exemple de configuration de contraintes dans le générateur Interface

 Interface builder

De plus, j'ai écrit des classes de cellules personnalisées pour UITextField _ et UITextViewtableView: didSelectRowAtIndexPath: est appelée lorsque la cellule est sélectionnée!

(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} _

La hauteur de la cellule est dynamique et la ligne s'agrandit lorsque le texte est transformé en une nouvelle ligne!

//
//  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
1
Ako

Le moyen le plus simple d'utiliser DateCell dans la version Swift: Utilisez cet exemple

  1. Ouvrez cet exemple et testez-le (Make Xcode to Convert to Swift 2)
  2. Faites glisser la classe "DateCellTableViewController.Swift} _" dans votre projet.

  3. Ouvrez "Main.storyboard" et copiez "DateCell} _" ViewController Object et collez-le dans votre story-board.

0
Ahmed Lotfy