Get indexpath If user edit the UITextfield in UITableview - ios

I'm using the UITableview like below image. If i typing Unit price and Qty i need to calculate. But now i dont know how to get indexpath for two text box in UITableView . In UITableView if button clicking goes to didSelectRowAtIndexPath method. Same method not calling when I typing in qty and unitprice textbox.
InvoiceMainViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#class InvoiceGridViewController;
#protocol InvoiceTableCellProtocoll <NSObject>
-(void) didPressButton:(InvoiceGridViewController *)theCell;
#end
#interface InvoiceGridViewController : UITableViewCell {
id<InvoiceTableCellProtocoll> delegationListener; }
#property (nonatomic,assign) id<InvoiceTableCellProtocoll> delegationListener;
#property (nonatomic,retain) IBOutlet UITextField *invoiceItem;
#property (nonatomic,retain) IBOutlet UITextField *invoiceUnitPrice;
#property (nonatomic,retain) IBOutlet UITextField *invoiceQty;
#property (nonatomic,retain) IBOutlet UITextField *invoiceTaxRate;
#property (nonatomic,retain) IBOutlet UILabel *invoiceItemId;
#property (nonatomic,retain) IBOutlet UILabel *invoiceCurrencyId;
#property (nonatomic,retain) IBOutlet UILabel *invoiceTaxRateId;
#property (nonatomic,retain) IBOutlet UILabel *totalItemTax; #property
#property (nonatomic,retain) IBOutlet UILabel *converstionMessage;
-(IBAction)deleteSel:(id)sender;
-(void)delFileSel;
#end
InvoiceMainViewController.m
#import <UIKit/UIKit.h>
#import "SBPickerSelector.h"
#import <Foundation/Foundation.h>
#import "AFHTTPRequestOperationManager.h"
#import "AFURLResponseSerialization.h"
#import "AFURLRequestSerialization.h"
#import "InvoiceGridViewController.h"
#interface InvoiceMainViewController : UIViewController<UITableViewDataSource, UITableViewDelegate,NSXMLParserDelegate,UITextFieldDelegate,InvoiceTableCellProtocoll>{

you can do this in various methods
Type -1
// get the current visible rows
NSArray *paths = [yourtableName indexPathsForVisibleRows];
NSIndexPath *indexpath = (NSIndexPath*)[paths objectAtIndex:0];
Type-2
you can get which cell you touched
CGPoint touchPoint = [sender convertPoint:CGPointZero toView: yourtableName];
NSIndexPath *clickedButtonIndexPath = [mainTable indexPathForRowAtPoint: yourtableName];
Type-3
add `TapGestuure ` for get the current cell.
Type-4
- (void) textFieldDidEndEditing:(UITextField *)textField {
CGRect location = [self convertRect:textField.frame toView:self.tableView];
NSIndexPath *indexPath = [[self.tableView indexPathsForRowsInRect:location] objectAtIndex:0];
// Save the contents of the text field into your array:
[yourArray replaceObjectAtIndex:indexPath.row withObject:textField.text];
}
example
here if you need additional information see this link

Try this one
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
firstTxt.delegate = self;
secondTxt.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
NSLog(#"textFieldShouldBeginEditing");
textField.backgroundColor = [UIColor colorWithRed:220.0f/255.0f green:220.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
NSLog(#"textFieldDidBeginEditing");
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
NSLog(#"textFieldShouldEndEditing");
textField.backgroundColor = [UIColor whiteColor];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(#"textFieldDidEndEditing");
[tableView reloadData];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"touchesBegan:withEvent:");
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
#pragma mark -
#pragma mark - UITableView Delegates
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:#"FirstTableViewCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"FirstTableViewCell"];
// cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (![firstTxt.text isEqual: #""] && ![secondTxt.text isEqual: #""])
{
NSString *fir = firstTxt.text;
NSString * sec = secondTxt.text;
cell.textLabel.text= [NSString stringWithFormat:#"%d",[fir intValue]+[sec intValue]];
}
else
{
cell.textLabel.text=#"";
}
//etc.
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// NSLog(#"testing1");
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.layer.backgroundColor = [UIColor clearColor].CGColor;
cell.backgroundColor = [UIColor clearColor];
}
#end
.h
//
// ViewController.h
// TestingText
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate>
{
IBOutlet UITableView *tableView;
IBOutlet UITextField *secondTxt;
IBOutlet UITextField *firstTxt;
}
#end

In textfield delegate method you can get the indexpath of row or you can directly get the textfields text
-(void)textFieldDidEndEditing:(UITextField *)textField
{
CGPoint hitPoint = [txtfield convertPoint:CGPointZero toView:tbl];
hitIndex = [tbl indexPathForRowAtPoint:hitPoint];
int localCount = [txtfield.text intValue];
}

Subclass your UITableViewCells. Create a protocol for each cell, with methods like cellName:(UITableViewCell*)cellName didSelectItem:(Item*) item. You can find more info here.
In the UITableViewCell set your UITextView delegate to self, and implement the protocol. textFieldShouldReturn: method, will indicate when the user is typing, so inside you will call [self.delegate cellName:self didEditText:textField.text].
In your MainViewController tableView: cellForRowAtIndexPath: set the UITabelViewCell's delegates, and implement the protocols.
So you will know in MainViewController when a user has typed in any of your textfields, independently from the table row number.

Related

Why my tableView stretch out?

I create a LMLUpspringChoosePeriodView and on it there is a tableView and a backgroundView,
I can use the LMLUpspringChoosePeriodView as the popup View, in my project.
This is the directory of it:
the LMLUpspringChoosePeriodView have ChoosePeriodTableViewHeader and LMLUpspringPeriodCell, all of them I create a XIB:
And In the LMLUpspringPeriodCell, I add the constraints to the name label, so it must be on the centre of the LMLUpspringPeriodCell:
But however, when I show the LMLUpspringChoosePeriodView as popup view, there comes an issue:
The tableView seems strech out of the screen.
My tableView's constraints is like this:
My code is below:
LMLUpspringChoosePeriodView.h:
typedef void(^LMLUpspringBlock)();
#import <UIKit/UIKit.h>
#interface LMLUpspringChoosePeriodView : UIView
#property (weak, nonatomic) IBOutlet UIView *upspringBackView;
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottom_tableView;
#property (nonatomic, copy) LMLUpspringBlock block;
- (void)showSelf;
- (void)hideSelf;
#end
LMLUpspringChoosePeriodView.m:
#import "LMLUpspringChoosePeriodView.h"
#import "LMLUpspringPeriodCell.h"
#import "ChoosePeriodTableViewHeader.h"
#interface LMLUpspringChoosePeriodView () <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *width_tableView;
#property (nonatomic, strong) NSArray *title_arr;
#end
#implementation LMLUpspringChoosePeriodView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (void)awakeFromNib {
[super awakeFromNib];
//_width_tableView.constant = KWidth;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 4;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
ChoosePeriodTableViewHeader *header = [[NSBundle mainBundle] loadNibNamed:#"ChoosePeriodTableViewHeader" owner:self options:nil].firstObject;
header.cancel_block = ^() {
[self hideSelf];
};
return header;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LMLUpspringPeriodCell *cell = [tableView dequeueReusableCellWithIdentifier:#"LMLUpspringPeriodCell"];
if (cell == nil) {
cell = [[NSBundle mainBundle] loadNibNamed:#"LMLUpspringPeriodCell" owner:self options:nil].firstObject;
}
// 配置cell
cell.title_label.text = self.title_arr[indexPath.row];
if (indexPath.row == 3) {
cell.bottom_line.hidden = YES;
}
[self setNeedsLayout];
[self layoutIfNeeded];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 48;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
LMLUpspringPeriodCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *period_str = cell.title_label.text;
self.block(period_str);
[self hideSelf];
}
#pragma mark - action
- (void)showSelf {
self.hidden = NO;
[UIView animateWithDuration:0.5 animations:^{
_bottom_tableView.constant = -49;
_upspringBackView.alpha = 0.3f;
}];
}
- (void)hideSelf {
_bottom_tableView.constant = -_tableView.bounds.size.height - 49;
[UIView animateWithDuration:0.25 animations:^{
_upspringBackView.alpha = 0.f;
[self layoutIfNeeded];
} completion:^(BOOL finished) {
if (finished) {
self.hidden = YES;
}
}];
}
- (IBAction)tapBackView:(id)sender {
[self hideSelf];
}
#pragma mark - setter
-(NSArray *)title_arr {
if (!_title_arr) {
_title_arr = #[#"当天", #"最近一周", #"最近一个月", #"最近三个月"];
}
return _title_arr;
}
#end
The ChoosePeriodTableViewHeader.h:
#import <UIKit/UIKit.h>
typedef void(^CancelChooseUpspringView)();
#interface ChoosePeriodTableViewHeader : UIView
#property (nonatomic, copy) CancelChooseUpspringView cancel_block;
#end
The ChoosePeriodTableViewHeader.m:
#import "ChoosePeriodTableViewHeader.h"
#implementation ChoosePeriodTableViewHeader
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
// 取消
- (IBAction)cancel:(UIButton *)sender {
self.cancel_block();
}
The LMLUpspringPeriodCell.h:
#import <UIKit/UIKit.h>
typedef void(^ConfirmChoosePeriod)(NSString *);
#interface LMLUpspringPeriodCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *title_label;
#property (weak, nonatomic) IBOutlet UIView *bottom_line;
#property (nonatomic, copy) ConfirmChoosePeriod confirm_block;
#end
The LMLUpspringPeriodCell.m:
#import "LMLUpspringPeriodCell.h"
#implementation LMLUpspringPeriodCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
I have tried use the below code in the awakeFromNib method in the LMLUpspringChoosePeriodView.m(you can see the LMLUpspringChoosePeriodView.m code, there is annotation in the awakeFromNib method ):
_width_tableView.constant = KWidth;
Replace of the tableView using trailling to constraint the tableView, it still strech out, but use the below code :
_width_tableView.constant = KWidth / 2;
It is perfect in iPhone7, but have issue in iPhone7 Plus:
So, it is a very strange issue here, how to do with that?
Not enough, there is second issue, the last item can not click, I don't know if is related to the tabbar.
How to solve the two issue? Thanks in advance.
EDIT -1
I add the LMLUpspringChoosePeriodView to the kwyWindow on a VC:
#property (nonatomic, strong) LMLUpspringChoosePeriodView *upspring_v;
....
[[UIApplication sharedApplication].keyWindow addSubview:self.upspring_v];
EDIT -2
This is my PurchaseRecordVC.m, in there I show the LMLUpspringChoosePeriodView:
#import "PurchaseRecordVC.h"
#import "LMLUpspringChoosePeriodView.h"
#interface PurchaseRecordVC ()
#property (nonatomic, strong) LMLUpspringChoosePeriodView *upspring_v;
#end
#implementation PurchaseRecordVC
- (void)viewDidLoad {
[super viewDidLoad];
[self initData];
[self initUI];
}
#pragma mark - init
- (void)initData {
}
- (void)initUI {
// 添加界面
[[UIApplication sharedApplication].keyWindow addSubview:self.upspring_v];
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
- (IBAction)clickTheChoosePeriod:(UIButton *)sender {
[_upspring_v showSelf];
}
#pragma mark - getter
- (LMLUpspringChoosePeriodView *)upspring_v {
if (!_upspring_v) {
_upspring_v = [[NSBundle mainBundle] loadNibNamed:#"LMLUpspringChoosePeriodView" owner:self options:nil].firstObject;
// 初始化
_upspring_v.upspringBackView.alpha = 0;
_upspring_v.bottom_tableView.constant = -_upspring_v.tableView.bounds.size.height - 49;
_upspring_v.hidden = YES;
_upspring_v.block = ^(NSString *period){
};
}
return _upspring_v;
}
#pragma mark - dealloc
- (void)dealloc {
// 移除界面
[self.upspring_v removeFromSuperview];
}
#end
I created a playground satisfying the same conditions, but altered it a bit for you to use as an example
Here you go:
https://wetransfer.com/downloads/7cf7267e51b7d265204a3ceaed48d0fd20170424125153/c92374

My tableview's cell is not displayed

FirstPage.h
#import <UIKit/UIKit.h>
#import "StudentPage.h"
#interface FirstPage : UIViewController <UITableViewDelegate,UITableViewDataSource,StudentInfoDelegates>
#property (strong, nonatomic) IBOutlet UITableView *tableView;
- (IBAction)addButtonAction:(id)sender;
#end
FirstPage.m
#import "FirstPage.h"
#interface FirstPage ()
#end
#implementation FirstPage
{
NSMutableArray *firstPageArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
//[self performSegueWithIdentifier:#"StudentInfo" sender:sender];
/*StudentPage *student=[[StudentPage alloc]init];
student.delegates=self;*/
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//the next following didn't created..
//the RowAtIndexPath are not been executed..
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *concateValue=#"";
NSMutableDictionary *studentSecondDictionary=[[NSMutableDictionary alloc]init];
static NSString *CellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell=[[UITableViewCell alloc]initWithFrame:CGRectZero];
[cell setBackgroundColor:[UIColor redColor]];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setIndentationWidth:0.0];
studentSecondDictionary=[firstPageArray objectAtIndex:indexPath.row];
NSString *name1=[studentSecondDictionary valueForKey:#"NAME"];
NSString *regno1=[studentSecondDictionary valueForKey:#"REGNO"];
NSString *marks1=[studentSecondDictionary valueForKey:#"MARKS"];
NSString *rank1=[studentSecondDictionary valueForKey:#"RANK"];
concateValue=[[[[[[name1 stringByAppendingString:#" "]stringByAppendingString:regno1]stringByAppendingString:#" "]stringByAppendingString:marks1]stringByAppendingString:#" "]stringByAppendingString:rank1];
cell.textLabel.text=concateValue;
}
return cell;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return firstPageArray.count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}
- (IBAction)addButtonAction:(id)sender {
StudentPage *stdView=[self.storyboard instantiateViewControllerWithIdentifier:#"MyIdentifier"];
stdView.delegates=self;
[self.navigationController pushViewController:stdView animated:YES];
//[self.view addSubview:stdView.view];
}
-(void)didFinishSave:(NSMutableArray *)in_studentList{
firstPageArray=[[NSMutableArray alloc]init];
firstPageArray=in_studentList;
[self.tableView reloadData];
}
#end
StudentPage.h
#import <UIKit/UIKit.h>
#protocol StudentInfoDelegates
-(void)didFinishSave:(NSMutableArray*)in_studentList;
#end
#interface StudentPage : UIViewController<UITextFieldDelegate>
#property(assign,nonatomic)id<StudentInfoDelegates> delegates;
#property (strong, nonatomic) IBOutlet UITextField *name;
#property (strong, nonatomic) IBOutlet UITextField *regno;
#property (strong, nonatomic) IBOutlet UITextField *marks;
#property (strong, nonatomic) IBOutlet UITextField *rank;
- (IBAction)save:(UIButton *)sender;
#end
StudentPage.m
#import "StudentPage.h"
#import "FirstPage.h"
#implementation StudentPage
{
NSMutableArray *studentArray;
NSMutableDictionary *StudentDictionary;
}
#synthesize name,regno,marks,rank;
#synthesize delegates;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
- (IBAction)save:(UIButton *)sender {
studentArray=[[NSMutableArray alloc]init];
StudentDictionary=[[NSMutableDictionary alloc]init];
[StudentDictionary setValue:name.text forKey:#"NAME"];
[StudentDictionary setValue:regno.text forKey:#"REGNO"];
[StudentDictionary setValue:marks.text forKey:#"MARKS"];
[StudentDictionary setValue:rank.text forKey:#"RANK"];
[studentArray addObject:StudentDictionary];
[delegates didFinishSave:studentArray];
NSLog(#"%#",studentArray);
FirstPage *firstView=[self.storyboard instantiateViewControllerWithIdentifier:#"MyIdentifier1"];
[self.navigationController pushViewController:firstView animated:YES];
}
#end
As #BiWoj said in the comments, you are checking for
if (cell==nil)...
and rely on that check to go through the first time so you can fill out your data. This is wrong, you instead dequeue the cell and then when it's not nil you can start putting your data in its views. The only reason that cell will be nil is when you dequeue, using a non-existent identifier i.e. it should never happen.
First just check your delegate method is getting called or not when you click on save button.
I think you forgot to set delegate to self before
[delegates didFinishSave:studentArray];
It should be
self.delegate = delegates
[delegates didFinishSave:studentArray];
If this does not work please check that, you are pushing student page from first page like this
- (IBAction)addButtonAction:(id)sender {
StudentPage *stdView=[self.storyboard instantiateViewControllerWithIdentifier:#"MyIdentifier"];
stdView.delegates=self;
[self.navigationController pushViewController:stdView animated:YES];}
And one again on your save action method of student page you are pushing first page like this.
FirstPage *firstView=[self.storyboard instantiateViewControllerWithIdentifier:#"MyIdentifier1"];
[self.navigationController pushViewController:firstView animated:YES];
Well i guess instead of that you have to just use
[self.navigationController popToRootViewControllerAnimated:YES];
There is no need to push again the same controller you just have to pop to base controller.

Unexpected delay when presenting UITableViewController

I have a custom UITableViewCell in a UITableViewController, but when the Controller tries to dequeue the custom cell, it will take a long time (like 2000ms).
This line of code causes the problem
KidsListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"kidsReuseIdentifier" forIndexPath:indexPath];
The KidsListTableViewCell is a custom cell, which includes couple of UIButtons, some UILabels to show the information. And two delegate methods. It shouldn't be that slow to render that view. By the way, all of the information in the custom cell is basically static.
The is the full code of the UITableViewController. I put the custom view and regular view in different sections and I don't think this causes the problem.
#import "KidDetailTableViewController.h"
#import "KidDetailHeaderTableViewCell.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import "Helper.h"
#interface KidDetailTableViewController () <KidDetailHeaderCellDelegate>
#end
#implementation KidDetailTableViewController
{
KidDetailHeaderTableViewCell *headerCell;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"KidDetailHeader" bundle:nil] forCellReuseIdentifier:#"kidDetail"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"detailCell"];
self.tableView.showsVerticalScrollIndicator = NO;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (section) {
case 0:
return 1;
break;
default:
return 10;
break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
if (!headerCell) {
headerCell = [tableView dequeueReusableCellWithIdentifier:#"kidDetail"];
headerCell.delegate = self;
// Keep the background color for the cell when select.
headerCell.selectionStyle = UITableViewCellSelectionStyleNone;
headerCell.nicknameLabel.text = _kidNeedsToShow.nickname;
NSString *kidFullName = [NSString stringWithFormat:#"%# %# %#", _kidNeedsToShow.firstName, _kidNeedsToShow.midName, _kidNeedsToShow.lastName];
kidFullName ? (headerCell.fullNameLabel.text = #"") : (headerCell.fullNameLabel.text = kidFullName);
// Set thumb image or use default
// if there isn't image, use default.
ALAssetsLibrary *library = [ALAssetsLibrary new];
[library assetForURL:_kidNeedsToShow.photoURL resultBlock:^(ALAsset *asset) {
[headerCell.avatarImage setImage:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]]];
} failureBlock:nil];
return headerCell;
}
else return headerCell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"detailCell" forIndexPath:indexPath];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 290;
}
else return 60;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 290;
}
else return 60;
}
- (void)didClickLeftButton:(UIButton *)leftButton {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
I tried to put dequeueReusableCellWithIdentifier into a different thread, apparently it wouldn't work.
UPDATE: KidDetailHeaderTableViewCell.m
- (void)awakeFromNib {
// Initialization code
[_avatarImage.layer setCornerRadius:_avatarImage.frame.size.width / 2];
[_avatarImage.layer setBorderColor:[UIColor whiteColor].CGColor];
[_avatarImage.layer setBorderWidth:1.0];
[_avatarImage setClipsToBounds:YES];
}
- (IBAction)leftButtonClicked:(UIButton *)sender {
if (self.delegate && [self.delegate respondsToSelector:#selector(didClickLeftButton:)]) {
[self.delegate didClickLeftButton:sender];
}
}
- (IBAction)rightButtonClicked:(UIButton *)sender {
if (self.delegate && [self.delegate respondsToSelector:#selector(didClickRightButton:)]) {
[self.delegate didClickRightButton:sender];
}
}
KidDetailHeaderTableViewCell.h
#protocol KidDetailHeaderCellDelegate <NSObject>
#optional
- (void)didClickLeftButton:(UIButton *)leftButton;
- (void)didClickRightButton:(UIButton *)rightButton;
#end
#interface KidDetailHeaderTableViewCell : UITableViewCell
#property (weak) id<KidDetailHeaderCellDelegate> delegate;
#property (weak, nonatomic) IBOutlet UILabel *fullNameLabel;
#property (weak, nonatomic) IBOutlet UIImageView *avatarImage;
#property (weak, nonatomic) IBOutlet UILabel *nicknameLabel;
#property (weak, nonatomic) IBOutlet UILabel *ageText;
#property (weak, nonatomic) IBOutlet UILabel *ageLabel;
#property (weak, nonatomic) IBOutlet UILabel *momentsStatistics;
#property (weak, nonatomic) IBOutlet UILabel *momentsLabel;
#property (weak, nonatomic) IBOutlet UIButton *rightButton;
#property (weak, nonatomic) IBOutlet UIButton *leftButton;
#end
UPDATE 2:
screenshot of instrument
The code for set the height of the cell. I have two sections, the first section actually is only used for header, the height is 290.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 290;
}
else return 60;
}
One of my friend pointed out that problem was caused by the custom font (Yes! I used custom font in the custom view). I still not sure about why this causes the problem (the font named 'hero'), but hope this will help someone else.

How do I enable a disabled textfield in a cell after typing in another one?

I have a table view controller with three cells, each with a textfield where a user defines:
-Country
-State (disabled)
-City (disabled)
How do I enable "State" textfield after the user types in "Country"?
The main problem is that I'm using a model called "Field", which has a property called "depends", which shows the id of the other Field that must not be empty.
My custom table view cell has a property "Field".
If I use "textfieldDidBeginEditing()" I can only access the textfield inside the cell, not the "Field" property.
All my cells are created dynamically.
The project is in Objective-C.
Its quite easy, here are your steps
Set textfield.delegate to your UIViewController
Implement UITextFieldDelegate method - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
Check for text length if needed
Grab next cell that u would like to enable using following code:
UITableViewCell *thisCell = [textView superCell];
NSIndexPath *thisIndexPath = [tableView indexPathForCell:thisCell];
NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:thisIndexPath.row inSection:thisIndexPath.section];
UITableViewCell *nextCell = [tableView cellForRowAtIndexPath: nextIndexPath];
Call becomeFirstResponder for a textField inside nextCell
You will need to create an UIView category with following method for code above to work
- (UITableViewCell *)superCell {
UIView *cell = self;
do {
cell = cell.superview;
} while( ![cell isKindOfClass:[UITableViewCell class]] && cell != nil );
return (UITableViewCell *)cell;
}
Short and simple:
For short list like your (table view can place all cells on the screen) it's will be enough to keep references to all three fields:
// Your model
#interface AddressStorageModel : NSObject
#property (strong, nonatomic) NSString* country;
#property (strong, nonatomic) NSString* state;
#property (strong, nonatomic) NSString* city;
#end
// Your cell
#interface FieldTableCell : UITableViewCell
#property (readonly, nonatomic) UITextField* textField;
#end
// Your view controller implementation
#implementation ViewController
{
__weak UITextField* _countryField;
__weak UITextField* _stateField;
__weak UITextField* _cityField;
AddressStorageModel* _addressStorage;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.textField.delegate = self;
switch (indexPath.row) {
case 0: // Country
_countryField = cell.textField;
break;
case 1: // State
_stateField = cell.textField;
break;
case 2: // City
_cityField = cell.textField;
break;
}
return cell;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// Validate somehow and move cursor to next field:
if (textField.text.length) {
UITextField* nextTextField = [self p_textFieldNextTo:textField];
[nextTextField setEnabled:YES];
[nextTextField becomeFirstResponder];
}
}
- (UITextField *)p_textFieldNextTo:(UITextField *)textField
{
if (textField == _countryField)
return _stateField;
else if (textField == _stateField)
return _cityField;
return _countryField;
}
- (void)completeButtonAction:(id)sender
{
_addressStorage.country = _countryField.text;
_addressStorage.state = _stateField.text;
_addressStorage.city = _cityField.text;
}
More complicated ... but simpler for future support
But if you plan to increase number of fields you should implement your code in this way:
// Your model
#interface AddressField : NSObject
#property (strong, nonatomic) NSString* title;
#property (strong, nonatomic) NSString* value;
#property (strong, nonatomic) AddressField* dependency;
#property (strong, nonatomic) NSIndexPath* indexPath;
#end
// Your cell
#protocol FieldTableCellDelegate <NSObject>
#required
- (void)fieldCellDidEndEditing:(FieldTableCell*)cell;
#end
#interface FieldTableCell : UITableViewCell <UITextFieldDelegate>
#property (readonly, weak, nonatomic) AddressField* addressField;
#property (weak, nonatomic) id<FieldTableCellDelegate> delegate;
- (void)configureForField:(AddressField *)field;
- (void)startEditing;
#end
#implementation ViewController
{
NSArray * _fields; // I left to your discretion how to create fields and assign dependencies
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _fields.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.delegate = self;
AddressField * field = _fields[indexPath.row];
field.indexPath = indexPath;
[cell configureForField:field];
return cell;
}
- (void)fieldCellDidEndEditing:(FieldTableCell *)cell
{
typeof(self) __weak weakSelf = self;
[UIView animateWithDuration:0.25
animations:^{
[weakSelf.tableView scrollToRowAtIndexPath:cell.addressField.dependency.indexPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:NO];
}
completion:^(BOOL finished) {
FieldTableCell* nextCell = (FieldTableCell*)[weakSelf.tableView cellForRowAtIndexPath:cell.addressField.dependency.indexPath];
[nextCell startEditing];
}];
}
#end
#implementation FieldTableCell
{
UITextField* _inputField;
}
- (void)configureForField:(AddressField *)field
{
_addressField = field;
_inputField.text = field.value;
_inputField.placeholder = field.title;
// do all other configurations...
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField.text.length > 0) {
_addressField.value = textField.text;
[_delegate fieldCellDidEndEditing:self];
}
}
- (void)startEditing
{
[_inputField becomeFirstResponder];
}
#end
use textFielShouldBeginEditing method of UITextFieldDelegate
Declaration
SWIFT
optional func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool
OBJECTIVE-C
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
example-
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//do state button enabled task here
}
With a button:
-(IBAction) continueButton: (UIButton*) sender{
//check if the state textfield is not empty in order to proceed
if(![self.stateTextfield.text isEqualToString: #""]){
self.cityTextfield.enabled = YES;
}
}
Simple get around but not really clean.
UPDATE
Use a normal View Controller.
Drag a Container View into the View Controller to allow for the size of your tableview that captures data.
Delete the automatically generated View Controller and drag a Table View Controller onto the storyboard and embed it in the Container View (ctrl + drag and select the embed in option)
Set this table view to Static.
Drag a TableView (not TableViewController) into the the ViewController.
Ctrl + drag the from TableView to the View Controller icon and set datasource and delegate. This will allow for data to load into the tableview.
This should now solve any issues with loading data as the data will load into the dynamic tableview and the static tableview will be unaltered (if this is a viable option for you). This way you can connect your textfields to your view controller and access their properties.
If you need any help or this isn't a good solution let me know.

Tableview button get index.row

I got a button in a tableview cell (named "deleteTemplate"), and when it's pressed i should get the "index.row" for the cell the button is in. Anybody knows how to get the "index.row" for the cell, when you click a button in the cell?
My current code for the button:
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonIndexPath = [self.tableView indexPathForCell:clickedCell];
NSDictionary *dic = [tableData objectAtIndex:clickedButtonIndexPath.row];
But clickedButtonIndexPath = NULL? :(
This worked in iOS 6.
Thank you!!!
You are getting null because the view hierarchy in iOS 7 is changed.
I recommend to use Delegate for getting the indexpath of TableViewCell.
You can get the sample project from here
Here is the sample:
My View Controller looks like this:
//#import "ViewController.h"
//#import "MyCustomCell.h"
#interface ViewController ()
{
IBOutlet UITableView *myTableView;
NSMutableArray *dataSourceArray;
}
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
dataSourceArray = [[NSMutableArray alloc] init];
for(int i=0;i<20;i++)
[dataSourceArray addObject:[NSString stringWithFormat:#"Dummy-%d",i]];
}
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
//pragma mark - UITableView Delegate And Datasource -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return dataSourceArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdenfifier = #"MyCustomCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdenfifier forIndexPath:indexPath];
[cell setDelegate:self];
[cell.myButton setTitle:[dataSourceArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];
return cell;
}
//pragma mark - MyCustomCell Delegate -
-(IBAction)myCustomCellButtonTapped:(UITableViewCell *)cell button:(UIButton *)sender
{
NSIndexPath *indexPath = [myTableView indexPathForCell:cell];
NSLog(#"indexpath: %#",indexPath);
}
#end
MyCustomCell.h looks like this:
//#import
#protocol MyCustomCellDelegate
#optional
- (IBAction)myCustomCellButtonTapped:(UITableViewCell *)cell button:(UIButton *)sender;
#end
#interface MyCustomCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#property(nonatomic, weak)id delegate;
#end
MyCustomCell.m looks like this:
//#import "MyCustomCell.h"
#implementation MyCustomCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
-(void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
//#pragma mark - My IBActions -
-(IBAction)myCustomCellButtonTapped:(UIButton *)sender
{
if([self.delegate respondsToSelector:#selector(myCustomCellButtonTapped:button:)])
[self.delegate myCustomCellButtonTapped:self button:sender];
}
#end
you set tag for your button in cellforrowatindexpath
clickedButtonIndexPath.tag=indexpath.row;
when button is presse in action write
nslog(#"%i",btutton.tag);
if clickedbuttonindexpath is nil it wont uitableviewcell
This question is already answered many times. For completion, here is the best solution:
-(IBAction)cellButtonTapped:(UIButton *)sender
{
CGRect buttonFrame = [sender convertRect:sender.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];
}
when you make the cell assign at you button.tag the indexPath.row and when you click the button in your method you have the sender (the button) and you get the indexPath from the sender's tag

Resources