Resize of section header in UITableViewController not working properly - ios

I am trying to resize a section header, according to a selection in the headers UISegmentedControl.
For some reason, it just doesn't want to work. I have tried with [self.tableView beginUpdates]; and [self.tableView endUpdates]; before, around and after the change-height code.. but it just act weird.
I get it to hide and show content, but it seems to allocate a different height for the view even thought the size of the header should be less.
This is what happens:
https://dl.dropboxusercontent.com/u/3077127/Problem3.mov
This is my code:
typedef enum {
kSearchTypeFrom = 0,
kSearchTypeTo
} kSearchType;
#interface MainVC ()
#property (nonatomic, strong) FilterVC *filterView;
#property (nonatomic, assign) kSearchType searchType;
#end
#implementation MainVC
#synthesize filterView = _filterView;
#synthesize searchType = _searchType;
[...]
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.searchType = kSearchTypeFrom;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
// Configure the cell...
[cell.detailTextLabel setText:#"Test"];
return cell;
}
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (!self.filterView) {
self.filterView = [[FilterVC alloc] init];
[self.filterView.view setBackgroundColor:self.navigationController.navigationBar.barTintColor];
}
[self.filterView.segment setSelectedSegmentIndex:self.searchType];
[self.filterView.segment addTarget:self action:#selector(didChangeSegmentSelection:) forControlEvents:UIControlEventValueChanged];
return self.filterView.view;
}
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.searchType == kSearchTypeFrom)
{
return 130;
}
else {
return 100;
}
}
#pragma mark - Height change table section
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
[self.tableView endUpdates];
[self.filterView.view needsUpdateConstraints];
}
[...]
The FilterVC class is nothing more than an UIViewController containing the following:
#import "InsetTextField.h"
#interface FilterVC : UIViewController
#property (nonatomic, strong) IBOutlet InsetTextField *amountField;
#property (nonatomic, strong) IBOutlet UISegmentedControl *segment;
#property (nonatomic, strong) IBOutlet UIButton *fromButton;
#property (nonatomic, strong) IBOutlet UILabel *changeToText;
#property (nonatomic, strong) IBOutlet UIButton *changeToButton;
#end
What is it that I am doing wrong?

As an alternate to trying to animate, you could try reloading the table using the following:
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
//[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
//[self.tableView endUpdates];
[self.tableView reloadData];
[self.filterView.view needsUpdateConstraints];
}
EDIT:
How about a variable to track height? This is sloppy code, but if the concept works, you can refactor it:
// Declare a variable
#proprty (strong, nonatomic) float headerHeight;
// Use that variable for defining the height
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.searchType == kSearchTypeFrom)
{
headerHeight = 130;
}
else {
headerHeight = 100;
}
return headerHeight
}
Then change that variable:
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
// Change the variable used for the header height
if (self.searchType == kSearchTypeFrom)
{
headerHeight = 130;
}
else {
headerHeight = 100;
}
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
[self.tableView endUpdates];
[self.filterView.view needsUpdateConstraints];
}

Related

UITextView auto expand in UITableView

I have a UITextView at the last row of UITableView. I want to auto expand the UITextView according to the text which is working fine. But as the UITextView expands, the UITableViewCell should also expand. I tried reloadRowsAtIndexPaths in textViewDidChange but that again and again reloads the cell causing the UITextView resignFirstResponder.
This is the code :
- (void)textViewDidChange:(UITextView *)textView
{
CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;
[tableMessageDetail beginUpdates];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(int)txtReplyBottom.tag inSection:0];
[tableMessageDetail reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableMessageDetail endUpdates];
}
Gif
Cell-AutoLayout
I add a height constraint with >= 50
Code
#interface SelfSizingCell ()<UITextViewDelegate>
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
#property (weak, nonatomic) IBOutlet UITextView *textview;
#end
#implementation SelfSizingCell
- (void)awakeFromNib {
// Initialization code
self.textview.delegate = self;
self.textview.scrollEnabled = false;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)textViewDidChange:(UITextView *)textView{
CGSize size = [textView sizeThatFits:CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX)];
CGFloat height = size.height;
if (height < 50) {
self.heightConstraint.constant = 50;
}else{
self.heightConstraint.constant = height;
}
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
#end
.h
#interface SelfSizingCell : UITableViewCell
#property (weak,nonatomic)UITableView * tableView;
#end
And tableviewController
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"SelfSizingCell" bundle:nil] forCellReuseIdentifier:#"cell"];
self.tableView.estimatedRowHeight = 50;
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SelfSizingCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.tableView = self.tableView;
return cell;
}

Why UiTextField from customTableViewCell not returning string in my UiViewController with UITableView

My project has a custom UITableViewCell with an UIImage and an UITextField.
In a view controller with a UITableView, I can access and set the customCell property from ViewController UITableView using datasource and delegate protocol.
The problem is when want to NSLog UITextField text using method textFieldShouldReturn.
Below is my code and snapshot of tableview in viewController.
CustomModalTableViewCell
#import <UIKit/UIKit.h>
#interface CustomModalTableViewCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UITextField *customCellTextField;
#property (strong, nonatomic) IBOutlet UIImageView *customCellImageView;
#end
ModalViewController.h
#import <UIKit/UIKit.h>
#interface ModalViewController : UIViewController<UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate>
#end
ModalViewController.m
#import "ModalViewController.h"
#import "CustomModalTableViewCell.h"
#import "MYImageClass"
#interface ModalViewController (){
CustomModalTableViewCell *customCell;
NSString *bookFieldString;
}
#property (strong, nonatomic) IBOutlet UITableView *modalTable;
#end
#implementation ModalViewController
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"book textFiled value is %#", customCell.customCellTextField.text);
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
customCell.customCellTextField.delegate = self;
self.modalTable.delegate = self;
self.modalTable.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return 2;
}else{
return 1;
}
return 0;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 20;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return #"Book Details";
}else if (section == 1){
return #"Reading Details";
}
return #"ok";
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomModalTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"customCellForModal"];
if (!cell) {
[tableView registerNib:[UINib nibWithNibName:#"customModalTableViewCell" bundle:nil] forCellReuseIdentifier:#"customCellForModal"];
cell = [tableView dequeueReusableCellWithIdentifier:#"customCellForModal"];
}
if (indexPath.section == 0) {
if (indexPath.row == 0) {
cell.customCellImageView.image = [MYImageClass imageOfBookIcon];
cell.customCellTextField.placeholder = #"Enter book name here";
}if (indexPath.row == 1) {
cell.customCellImageView.image = [MYImageClas imageOfAuthorIcon];
cell.customCellTextField.placeholder = #"Enter author name here";
}
}else if (indexPath.section == 1){
if (indexPath.row == 0) {
cell.customCellImageView.image = [MYImageClas imageOfTotalPageIcon];
cell.customCellTextField.placeholder = #"Enter total page here";
}
}
return cell;
}
#end
The problem with your code is, you are confused about the concept of delegates and tableviews.
a. First off Get rid of that global variable named customCell. You don't need that and you are not using that.
b. In your cellForRowAtIndexPath method, type this line after declaring the cell.
cell.customCellTextField.delegate = self;
c. Replace your delegate method for textField, textFieldShouldReturn with this:
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(#"book textFiled value is %#", textField.text);
return YES;
}

-didSelectRowAtIndexPath: not being called in UITableView

When I click the UITableViewCell , It have selection effect (grey background in clicked cell),But didSelectRowAtIndexPath is not calling ,what happen?
EDIT
this is my code
tableView.h file
#interface PopCardView : MMPopupView <UITableViewDataSource, UITableViewDelegate>
#end
tableView.m file
#property (nonatomic, strong) NSMutableArray *tagsArray;
#property (nonatomic, strong) UIView *backView;
#property (nonatomic, strong) UITableView *tableView;
#property (nonatomic, assign) NSUInteger lastIndex;
#end
-(id)initWithTags:(NSMutableArray *)tags{
self = [super init];
if (self) {
self.backView = [[UIView alloc] init];
self.backView.backgroundColor = [UIColor whiteColor];
self.backView.layer.cornerRadius = 5;
self.backView.layer.masksToBounds = YES;
[self addSubview:self.backView];
[self.backView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.right.equalTo(self);
}];
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 324, 300) style:UITableViewStylePlain];
_tableView.tableFooterView =[[UIView alloc] init];
[self.backView addSubview:_tableView];
[_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.bottom.equalTo(self.backView).insets(UIEdgeInsetsMake(45,0, 45, 15));
make.size.mas_equalTo(CGSizeMake(324, 200));
}];
[_tableView registerClass:[PopCardTagViewCell class] forCellReuseIdentifier:#"cell"];
_tableView.allowsSelection = YES;
_tableView.allowsSelectionDuringEditing = YES;
[_tableView setUserInteractionEnabled:YES];
_tableView.dataSource = self;
_tableView.delegate = self;
}
return self;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_tagsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
PopCardData *data = (PopCardData *)obj;
data.selected = #"0";
if (idx == indexPath.row) {
data.selected = #"1";
}
}];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifer = #"cell";
PopCardTagViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell) {
cell = [[PopCardTagViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
[self configureCell:cell forIndexPath:indexPath];
return cell;
}
-(void)configureCell:(PopCardTagViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
PopCardData *data = (PopCardData *)[_tagsArray objectAtIndex:indexPath.row];
//configure cell
[cell setUserInteractionEnabled:YES];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _tagsArray.count;
}
EDIT2
this is my initialize code of PopCardView,it use swift
let pop = PopCardView(tags: self.m_model.getItmes())
pop.show()
The code you show does not set any delegate to the table view. Either this is the reason or you posted an incomplete code snippet.
self.tableView.delegate = self;
and add UITableViewDelegate to your interface like
#interface ClassName ()<UITableViewDelegate>
Make sure you don't have anything in the cell that can swallow the touch event. Things like buttons and textfields can cause this. Strip everything from your cell, test to see if it works, then add things back in slowly to find the culprit.

Select one row in each section of UITableView ios?

Scenario:
I have made 2 sections in one UITableView and the user needs to select a row in each section as shown in the screenshot below.
Expected Outcome:
1. User should be able to select a row in each section
Outcome right now:
1. After I have selected row in one section, and then when I select the row in second section, the first selection disappears.
Here is my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Uncheck the previous checked row
long sec=indexPath.section;
if(sec==0){
if(self->checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self->checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
if([self->checkedIndexPath isEqual:indexPath])
{
self->checkedIndexPath = nil;
}
else
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self->checkedIndexPath = indexPath;
}}
if(sec==1){
if(self->checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self->checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
if([self->checkedIndexPath isEqual:indexPath])
{
self->checkedIndexPath = nil;
}
else
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self->checkedIndexPath = indexPath;
}
}
}
Help is appreciated.
This is the simplest way.
Finally i found a solution. It works for me, hope it will work for you.
declare these
#interface ViewController ()
{
int selectedsection;
NSMutableArray *selectedindex;
}
Replace didSelectRowAtIndexPath as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Uncheck the previous checked row
NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];
if(self.checkedIndexPath)
{
for (int i=0; i<[selectedindex count]; i++) {
NSIndexPath *temp= [selectedindex objectAtIndex:i];
if (temp.section==selectedIndexPath.section) {
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:temp];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
}
NSInteger numb= [tableView numberOfRowsInSection:selectedIndexPath.section];
if (selectedsection==selectedIndexPath.section) {
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
}
if([self.checkedIndexPath isEqual:indexPath])
{
for (int i=0; i<[selectedindex count]; i++) {
NSIndexPath *temp= [selectedindex objectAtIndex:i];
if (temp.section==selectedIndexPath.section) {
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:temp];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
}
self.checkedIndexPath = nil;
}
else
{
for (int i=0; i<[selectedindex count]; i++) {
NSIndexPath *temp= [selectedindex objectAtIndex:i];
if (temp.section==selectedIndexPath.section) {
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:temp];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
}
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
[selectedindex addObject:indexPath];
selectedsection=indexPath.section;
NSLog(#"check");
}
}
You can enable the multiple selection in the tableview:
self.tableView.allowsMultipleSelection = YES;
I wrote a sample code where a compound datasource holds datasource objects for each section. Sounds complicated but actually provides an easy to extend architecture. And keeps your view controller small.
The advantages of this approach:
Small ViewController
ViewController set ups view and handles user interaction — as it should be in MVC
Reusable datasources
by using different datasources per section easy to customize cells for each section
the base datasource architecture
This provides easy extension and is simple to reuse.
#import UIKit;
#interface ComoundTableViewDataSource : NSObject
#property (nonatomic,strong, readonly) NSMutableDictionary *internalDictionary;
-(void) setDataSource:(id<UITableViewDataSource>)dataSource forSection:(NSUInteger)section;
-(instancetype)initWithTableView:(UITableView *)tableView;
#end
#import "ComoundTableViewDataSource.h"
#interface ComoundTableViewDataSource () <UITableViewDataSource>
#property (nonatomic,strong, readwrite) NSMutableDictionary *internalDictionary;
#property (nonatomic, weak) UITableView *tableView;
#end
#implementation ComoundTableViewDataSource
-(instancetype)initWithTableView:(UITableView *)tableView
{
self = [super init];
if (self) {
_tableView = tableView;
tableView.dataSource = self;
_internalDictionary = [#{} mutableCopy];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
return self;
}
-(void)setDataSource:(id<UITableViewDataSource>)dataSource forSection:(NSUInteger)section
{
self.internalDictionary[#(section)] = dataSource;
[self.tableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.internalDictionary allKeys] count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id<UITableViewDataSource> sectionDataSource = self.internalDictionary[#(section)];
return [sectionDataSource tableView:tableView numberOfRowsInSection:section];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
id<UITableViewDataSource> sectionDataSource = self.internalDictionary[#(indexPath.section)];
return [sectionDataSource tableView:tableView cellForRowAtIndexPath:indexPath];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
id<UITableViewDataSource> sectionDataSource = self.internalDictionary[#(section)];
return [sectionDataSource tableView:tableView titleForHeaderInSection:section];
}
#end
#import UIKit;
#interface SingleSectionDataSource : NSObject <UITableViewDataSource>
#property (nonatomic, strong, readonly) NSArray *array;
#property (nonatomic, strong, readonly) UITableView *tableView;
- (instancetype)initWithArray:(NSArray *)array;
#end
#import "SingleSectionDataSource.h"
#interface SingleSectionDataSource ()
#property (nonatomic, strong, readwrite) NSArray *array;
#property (nonatomic, strong, readwrite) UITableView *tableView;
#end
#implementation SingleSectionDataSource
- (instancetype)initWithArray:(NSArray *)array
{
self = [super init];
if (self) {
self.array = array;
}
return self;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
self.tableView = tableView;
return self.array.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.array[indexPath.row];
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [#(section) stringValue];
}
#end
the selection datasource architecture
We extend the classes from above to allow one selection per section
#import "ComoundTableViewDataSource.h"
#interface OnSelectionPerSectionComoundTableViewDataSource : ComoundTableViewDataSource
-(void)selectedCellAtIndexPath:(NSIndexPath *)indexPath;
#end
#import "OnSelectionPerSectionComoundTableViewDataSource.h"
#import "SingleSelectionSingleSectionDataSource.h"
#implementation OnSelectionPerSectionComoundTableViewDataSource
-(instancetype)initWithTableView:(UITableView *)tableView
{
self = [super initWithTableView:tableView];
if(self){
[tableView setAllowsMultipleSelection:YES];
}
return self;
}
-(void)selectedCellAtIndexPath:(NSIndexPath *)indexPath
{
SingleSelectionSingleSectionDataSource *sectionDataSource = self.internalDictionary[#(indexPath.section)];
[sectionDataSource selectedCellAtIndexPath:indexPath];
}
#end
View Controller Implementation
As promised, a very slim view controller:
#interface ViewController () <UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (nonatomic, strong) OnSelectionPerSectionComoundTableViewDataSource *tableViewDataSource;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableViewDataSource = [[OnSelectionPerSectionComoundTableViewDataSource alloc] initWithTableView:self.tableView];
self.tableView.delegate = self;
[self.tableViewDataSource setDataSource:[[SingleSelectionSingleSectionDataSource alloc] initWithArray:#[#"Hallo", #"Welt"]] forSection:0];
[self.tableViewDataSource setDataSource:[[SingleSelectionSingleSectionDataSource alloc] initWithArray:#[#"Hello", #"World", #"!"]] forSection:1];
[self.tableViewDataSource setDataSource:[[SingleSelectionSingleSectionDataSource alloc] initWithArray:#[#"Hola", #"Mundo", #"!", #"¿Que tal?"]] forSection:2];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableViewDataSource selectedCellAtIndexPath:indexPath];
}
#end
You will want to add methods to the datasources to get the selected rows.
get the example: https://github.com/vikingosegundo/CompoundDatasourceExample
Note This code has a cell reuse issue. It is fixed on GitHub.

How to getlcell.label.text value of uitableview cell in a string

I am making an app in which i am using tableview and in each table cell i am using checkboxes. now i am stuck in this place that when checkbox is checked i want to get value of that table-cell. like i am showing messages id in table cell i want to get messages_Id of that cells whose checkboxes are checked. means if select 1 checkbox its message id is store in NSString and if i select 2 checkboxes then 2 messages of these checkboxes are store in string how it can be done.below is my sample code of tableview and check boxes action
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *tableviewidentifier = #"cell";
__block tablecellTableViewCell *cell= [self.activitiesTableView_ dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell==nil)
{
cell = [[tablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableviewidentifier];
}if(indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1){
}
__block NSString *row = [NSString stringWithFormat:#"%ld",(long)indexPath.row];
cell.titlename.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"offerTitle"];
tocity.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"toCity"];
fromcity.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"fromCity"];
date.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"messageDate"];
time.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"messageTime"];
[cell.button setBackgroundImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
[cell.button setImage:nil forState:UIControlStateNormal];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]])
{
[cell.button setImage:[UIImage imageNamed:#"tick.png"]// here i am setting image
forState:UIControlStateNormal];
cell.contentView.backgroundColor=[UIColor colorWithRed:(245/255.0) green:(245/255.0) blue:(245/255.0) alpha:1];
}
else
{
cell.backgroundColor=[UIColor clearColor];
}
cell.button.tag=indexPath.row;
[cell.button addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
and below is my check button code
-(IBAction)checkButton:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tblvie];
NSIndexPath *indexPath = [self.tblvie indexPathForRowAtPoint:buttonPosition];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=#"";
}
else {
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=[NSString stringWithFormat:#"%ld selected",(long)sender.tag+1];
}
[self.tblvie reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
and i want to get value of these checked boxes in this button
- (IBAction)menubtun:(id)sender {
}
there if want the cell info of selected cell, just handle the action method of tickButton in custom cell it self not in controller use below code define a protocol and define a delegate see the below code
in tablecellTableViewCell.h
#import <UIKit/UIKit.h>
#class tablecellTableViewCell;
#protocol CustomCellDelegate <NSObject>
- (void)checkBoxButtonSelected:(tablecellTableViewCell *)cell; //this is the custom delegate method
#end
#interface tablecellTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *profileImageView; //i changed the name for conventions
#property (weak, nonatomic) IBOutlet UIButton *tickButton;
#property (weak, nonatomic) IBOutlet UILabel *nameLabel; //valuedate
#property (weak, nonatomic) IBOutlet UILabel *messageLabel;
#property (weak, nonatomic) IBOutlet UILabel *dateLabel;
#property (weak, nonatomic) IBOutlet UILabel *timeLabel;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicatorView;
#property (weak, nonatomic) id<CustomCellDelegate> cellDelegate; //decleare a delegate hear
- (void)setFont:(UIFont *)font withString:(NSString *)title;
#end
and in tablecellTableViewCell.m all code is same but u have to connect a action to tickButton for example
#import "tablecellTableViewCell.h"
#implementation tablecellTableViewCell
//#synthesize button,image;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
}
return self;
}
- (void)awakeFromNib
{
// Initialization code
[super awakeFromNib];
[self setUp];
}
//...same code of yours no need to change just a action method of tick button is added extra
//in this call a delegate method by passing the entire cell itself
- (IBAction)checkButtonAction:(id)sender
{
if([self.cellDelegate respondsToSelector:#selector(checkBoxButtonSelected:)])
{
[self.cellDelegate checkBoxButtonSelected:self];//hear u are passing the enire cell to Fbinbox..controller
}
}
in the controller class .h file
//..same code just confirm to protocol
#interface inboxViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UIActionSheetDelegate,CustomCellDelegate> //confirm to protocol
{
int checkBoxesCount;
}
in .m file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
__block tablecellTableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell == nil)
{
cell = [[tablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableviewidentifier];
}
if(indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1)
{
}
__block NSString *row = [NSString stringWithFormat:#"%ld",(long)indexPath.row];
cell.activityIndicatorView.hidden = NO;
[cell.activityIndicatorView startAnimating];
if([[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"messageRead"] intValue]==0)
{
cell.contentView.backgroundColor=[UIColor colorWithRed:(245/255.0) green:(245/255.0) blue:(245/255.0) alpha:1];
}
else
{
cell.contentView.backgroundColor=[UIColor clearColor];
}
cell.messageLabel.text = [[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"toCity"];
cell.cellDelegate = self;//add this one line
//... rest same code but comment the action method of tick button
//..hear in the last
cell.tickButton.tag = indexPath.row;
// [cell.tickButton addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside]; //comemnt this line this tickbutton action is in custom cell
}
//now define custom delegate method
- (void)checkBoxButtonSelected:(tablecellTableViewCell *)cell //in this cell contains every thing including message and all
{
//hear u are getting the entire cell
//now u can get the all info stored in this cell
NSIndexPath *indexPath = [self.activitiesTableView_ indexPathForCell:cell];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
//....other stuff's
//cell.textLabel.text;
//..all info present in the cell
}
else
{
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
//..do other stuff
NSString *selectedMessage = cell.messageLabel.text;
//cell.textLabel.text;
//..all info present in the cell
NSLog(#"SELECTED MESSAGE->%#",selectedMessage);
}
[self.activitiesTableView_ reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}

Resources