How to change frame to title header (UITableView) - ios

How it is possible to change the x axis to my title header section in swift?
I'm not able to change it using that code:
func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
{
let header:UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
header.textLabel!.textColor = UIColor.darkGrayColor()
header.textLabel!.font = UIFont(name: "Arial", size: 12.0)!
header.textLabel!.textAlignment = NSTextAlignment.Left
header.backgroundView?.backgroundColor = UIColor.sectionGray()
//Not working
header.textLabel!.frame.origin.x = header.textLabel!.frame.origin.x - 60
}

header.textLabel!.frame = header.textLabel!.frame.offsetBy(dx: -60, dy: 0)

use view in exith for example
#import "ViewController.h"
#interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
#property (strong, nonatomic) IBOutlet UIView *tableView;
#property (strong, nonatomic) IBOutlet UITableView *myTable;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 10;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *tblCell = [tableView dequeueReusableCellWithIdentifier:#"gm" forIndexPath:indexPath];
return tblCell;
}
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return self.tableView;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 100;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

//Not working
header.textLabel!.frame.origin.x = header.textLabel!.frame.origin.x - 60
your cant not change the orign.x or orign.y but you can change the frame or update the frame
do one thing instead of this opproach
in your storyboard create one uitableviewCell and design it as you want and define its class and idntifire as SectionHeader
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
SectionHeaderTableViewCell *headerView = [tableView dequeueReusableCellWithIdentifier:#"SectionHeader"];
if (headerView == nil) {
headerView = (SectionHeaderTableViewCell*)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SectionHeader"];
}
headerView.headerTxt.text=#"THIS WEEK";
return headerView;
}
this is objective C code convert it in swift this is the most easiest way to play with header

Related

How to call one class delegate methods from another class

In table list using swift here i want to load the one class table-list in another class view controller and this concept is working in objective-c but come down to swift delegate methods are not calling my objective -c#swift codes below please help me some one else
BackGroundView.h:-
#import <UIKit/UIKit.h>
#interface BackGroundView
UIViewController<UITableViewDataSource,UITableViewDelegate>
{
UITableView *tableView;
}
#property(nonatomic, retain) UITableView *tableView;
-(void)tableList:(UIView *) view1;
#end
BackGroundView.m:-
#import "BackGroundView.h"
#interface BackGroundView ()
{
NSArray * Mainarray;
}
#end
#implementation BackGroundView
#synthesize tableView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)tableList:(UIView *) view1
{
Mainarray = [[NSArray alloc]initWithObjects:#"india",#"australia",#"usa", nil];
tableView=[[UITableView alloc]init];
tableView.frame = CGRectMake(0,0,320,400);
tableView.dataSource=self;
tableView.delegate=self;
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
[tableView reloadData];
tableView.separatorColor = [UIColor blackColor];
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
[view1 addSubview:tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return Mainarray.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath] ;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text= [Mainarray objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
#end
MaindView.h
#import <UIKit/UIKit.h>
#interface ViewController1 : UIViewController
#end
MaindView.m
#import "ViewController1.h"
#import "BackGroundView.h"
#interface MaindView ()
{
BackGroundView * v1;
}
#end
#implementation MaindView
- (void)viewDidLoad {
[super viewDidLoad];
v1 = [[BackGroundView alloc]init];
// Do any additional setup after loading the view.
[v1 tableList:self.view];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Now it's working fine in objective-c and table list is loading fine
come down to swift ios:-
Now i am calling TableViewAdding from Mainview class to BackgroundView it's calling but delegate methods are not calling in background class i.e it is showing empty view controller in swift table list is not loading properly please help me and this is my swift code
BackGroundView.swift
import UIKit
class BackGroundView: UIViewController,UITableViewDelegate, UITableViewDataSource {
var tableView: UITableView = UITableView()
var items = NSArray ()
override func viewDidLoad() {
super.viewDidLoad()
}
func TableViewAdding(myview:UIView)
{
items = ["india","australia","usa"];
println(items)
tableView.frame = CGRectMake(0, 50, 320, 200);
tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
myview.addSubview(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
println("numberOfRowsInSection")
return self.items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
println("cellForRowAtIndexPath")
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.items.objectAtIndex(indexPath.row) as NSString
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
println("in first")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Mainview.swift
import UIKit
class Mainview: UIViewController{
#IBOutlet var myview1: UIView!
override func viewDidLoad() {
super.viewDidLoad()
var total = BackGroundView.alloc()
total.TableViewAdding(self.view)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
[UPDATED]
You're not initializing the BackGroundView in mainview.swift. You're just allocating the memory for the object. Note that you both alloc and init a class in Objective-C. In Swift, you have to do the same thing with Class.alloc().initialize(). However, swift has replaced that verbose line of code with a simple call: Class()
Objective-C:
Class *myInstance = [[Class alloc] init];
Swift:
var myInstance = Class()
Some other things:
It's always a good idea to call tableView.reloadData() after you
change the information in it (like in your TableViewAdding) method.
It's never a good idea to hard code numbers (like the table view size).
TableViewAdding looks like a class method. tableViewAdding would follow the camelCase convention more accurately
Documentation for why using var myInstance = Class.alloc() is not the same as using var myInstance = Class() can be found in Apple's NSObject documentation under Creating, Copying, and Deallocating Objects
https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/index.html#//apple_ref/occ/clm/NSObject/alloc
Using KVC to get delegate property.
Using NSInvocation to call delegate method
Declare total as Class variable in Mainview.swift. Don't use .alloc()
import UIKit
class Mainview: UIViewController{
var total = BackGroundView()
#IBOutlet var myview1: UIView!
override func viewDidLoad() {
super.viewDidLoad()
total.TableViewAdding(self.view)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

UITableViewCell get deleted directly by tapping delete control on the left but not show delete button on the right

When I involve [tableView setEditing:YES animated:YES], delete control shows on every cell on the left,what I want to do is to get the event when I tap delete control,and directly delete cell but not to show delete button on the right.
I know apple's standard way to do this is to show delete button on the right, and when I tap it ,datasource's
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
gets involved, the reason I don't want to do like this is my cell is customised by scrollview which scroll horizontally so scroll to show delete button would made it a mess, so I wouldn't implement
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
in my datasource.
Have any idea?
one way u do is, customising the cell and put your own way of deleting the cell for example,
create a new custom cell by subclassing the UITableviewCell name it as something like CustomCellTableViewCell
in CustomCellTableViewCell.h define a delegate method for example,
#import <UIKit/UIKit.h>
#class CustomCellTableViewCell;
#protocol CellDelegate <NSObject>
- (void)deleteCell:(CustomCellTableViewCell *)cell;
#end
#interface CustomCellTableViewCell : UITableViewCell
+ (CustomCellTableViewCell *)createCell;
#property (weak, nonatomic) IBOutlet UIButton *deleteButton;
#property (weak, nonatomic) IBOutlet UILabel *descriptionLabel;
#property (weak,nonatomic) id<CellDelegate> cellDelegate;
- (IBAction)deleteAction:(id)sender;
- (void)showDeleteButton;
- (void)hideDeleteButton;
#end
and in CustomCellTableViewCell.xib add a button and set label connect to deleteButton and descriptionLabel
in CustomCellTableViewCell.m file
#import "CustomCellTableViewCell.h"
#implementation CustomCellTableViewCell
- (void)awakeFromNib {
// Initialization code
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
self = [CustomCellTableViewCell createCell];
}
return self;
}
+ (CustomCellTableViewCell *)createCell
{
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:#"CustomCellTableViewCell" owner:nil options:nil];
if ([arrayOfViews count] < 1) {
return nil;
}
for (id item in arrayOfViews) {
if([item isKindOfClass:[UITableViewCell class]])
return item;
}
return nil;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (IBAction)deleteAction:(id)sender {
if([self.cellDelegate respondsToSelector:#selector(deleteCell:)])
{
[self.cellDelegate deleteCell:self];
}
}
- (void)showDeleteButton
{
CGRect destRect = self.descriptionLabel.frame;
destRect.origin.x += 80;
[UIView animateWithDuration:0.3 animations:^{
self.descriptionLabel.frame = destRect;
}];
}
- (void)hideDeleteButton
{
CGRect destRect = self.descriptionLabel.frame;
destRect.origin.x = 0;
[UIView animateWithDuration:0.3 animations:^{
self.descriptionLabel.frame = destRect;
}] ;
}
#end
and in controller .m file
- (void)viewDidLoad {
[super viewDidLoad];
stringsArray = [[NSMutableArray alloc]initWithObjects:#"apple",#"dell",#"windows",#"nokia",#"sony",#"hp",#"lenovo", nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [stringsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SuggestionCell"];
if(cell == nil)
{
cell = [[CustomCellTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SuggestionCell"];
}
if(customEditTableView)
[cell showDeleteButton];
else
[cell hideDeleteButton];
cell.cellDelegate = self;
cell.descriptionLabel.text = [stringsArray objectAtIndex:indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50.0f;
}
- (IBAction)deleteCellsAction:(id)sender
{
if(customEditTableView)
customEditTableView = NO;
else
customEditTableView = YES;
[self.aTableView reloadData];
}
- (void)deleteCell:(CustomCellTableViewCell *)cell
{
NSIndexPath *indexPath = [self.aTableView indexPathForCell:cell];
[stringsArray removeObjectAtIndex:indexPath.row];
[self.aTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
try out in new project u will get it
You can achive this thing using UIViewController
Add tableview and tableviewcell in UIViewController
I have achive this same thing using swift. It will give you idea how to do in Objective-C
Below is Code:
var data:[String] = ["One","Three","Four","Five","Six"]
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = self.editButtonItem()
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel.text = self.data[indexPath.row]
if editing
{
cell.imageView.image = UIImage(named: "Button-Delete-icon.png")
}
else
{
cell.imageView.image = UIImage(named: "")
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if editing
{
self.data.removeAtIndex(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
}
}
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
self.tableView.reloadData()
}
Hope It will Help

UISearchBar: search results hidden behind the searchbar

I have implemented an empty ViewController i.e SearchViewController with a SearchBar in it. Ans as i am searching from a web service, i want the search results to be displayed only when the user presses the search button. That has been implemented. Bt the problem is, the results appear in a weird manner as shown below:
Dont know what are they getting hidden. How do i bring them to front??
Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
self.api.delegate = self
activateSearch()
searchTableView.delegate = self
searchTableView.dataSource = self
searchBar.delegate = self
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as UITableViewCell
var rowData: NSDictionary = self.tableData[indexPath.row] as NSDictionary
cell.textLabel?.text = rowData["title"] as? String
return cell
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
func didReceiveAPIResults(results: NSDictionary) {
var resultsArr: NSArray = results["posts"] as NSArray
dispatch_async(dispatch_get_main_queue(), {
self.tableData = resultsArr
self.searchTableView!.reloadData()
})
}
func activateSearch() {
// self.navigationController?.navigationBarHidden = true
searchTableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: false)
searchBar.becomeFirstResponder()
}
override func viewWillAppear(animated: Bool) {
var newBounds:CGRect = self.searchTableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.searchTableView.bounds = newBounds;
self.navigationController?.navigationBarHidden = true
}
func searchBarSearchButtonClicked( searchBar: UISearchBar!)
{
api.searchItunesFor(searchBar.text)
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
self.viewWillAppear(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
I might hv done something silly. bt m not able to figure out what is it.. pls help
It looks like your search bar has been placed over your table view. Try to scale your table view down in the storyboard so the top of the table view is below the search bar element. The results should display correctly
You are changing the searchTableView frame inside the viewWillAppear method which will not get call when you are in the same view controller.
Try changing the searchTableView frame inside the searchBarSearchButtonClicked method.
Hope this will solve your problem. :)
Edit:
Also try adding the search bar to the searchTableView header.
Below is the objective-c code for adding the search bar to the tableView header.
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)] ;
self.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
self.searchBar.keyboardType = UIKeyboardTypeAlphabet;
self.searchBar.delegate = self;
self.tableView.tableHeaderView = self.searchBar;
Just posting the answer incase someone ends in a situation like mine.
I didn't connect the tableView to the SearchDisplayController.
The tableView should be the dataSource and Delegate for the SearchDisplayController.
We just need to control+Drag to connect.
PS. in XCODE 6.1 the SearchDisplayController is displayed as a button like thing in the header of ViewController.
#import <UIKit/UIKit.h>
#interface TableViewController : UITableViewController
#end
#import "TableViewController.h"
#interface TableViewController () {
NSInteger _rows;
}
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
#end
#implementation TableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_rows = 3;
// [self hideSearchBar];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.tableView setContentOffset:CGPointMake(0,44) animated:NO];
// self.tableView.tableHeaderView = self.searchBar;
}
-(void)viewDidDisappear:(BOOL)animated{
//self.tableView.tableHeaderView = nil;
//[self.tableView.tableHeaderView removeFromSuperview];
[self.tableView setContentInset:UIEdgeInsetsMake(-0.3, 0, 0, 0)];
[super viewDidAppear:animated];
}
- (void)hideSearchBar {
// hide search bar
[self.tableView setContentOffset:CGPointMake(0,44) animated:NO];
}
- (IBAction)toggleCount:(UIBarButtonItem *)sender {
if (_rows == 20) {
_rows = 3;
} else {
_rows = 20;
}
[self.tableView reloadData];
}
- (IBAction)hideBar:(UIBarButtonItem *)sender {
[self hideSearchBar];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return _rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = #"cell";
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a story board-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.
}
*/
#end

iOS program to use multiple UITableView in a single UIViewController

I am trying to implement 3 tables in a single segue in a storyboard.
When one table is selected it will unhidden a view with another table and likewise one more.
The following code i have used for one table the cell format of each table is different and rows also vary. So how can i DIFFERENTIATE between each table by coding to set different number of rows for each table and so on?
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell2";
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell1==nil)
{
cell1=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
temp=[array objectAtIndex:indexPath.row];
UILabel *Label1 = (UILabel *)[cell1 viewWithTag:4];
Label1.text = temp.Title;
UILabel *Label2 = (UILabel *)[cell1 viewWithTag:6];
Label2.text = temp.Title;
UITextField *textfield1 = (UITextField *)[cell1 viewWithTag:5];
textfield1.text =temp.description;
UILabel *Label3 = (UILabel *)[cell1 viewWithTag:7];
Label3.text = temp.Title;
return cell1;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.showlist=[[ShowList alloc]initWithNibName:#"ShowList" bundle:nil];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
ShowlistIndex=indexPath.row;
_secondview.hidden=NO;
}
You should declare your tableViews in .h file.
#property (weak, nonatomic) UITableView *firstTableView;
#property (weak, nonatomic) UITableView *secondTableView;
#property (weak, nonatomic) UITableView *thirdTableView;
And then all the delegate methods have variable with pointing witch object call this method, so you can check:
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView == self.firstTableView)
return 3;
else if(tableView == self.secondTableView)
return 4;
else if(tableView == self.thirdTableView)
return 100;
}
The other delegate methods work in the same way.
You can keep track of the different tableviews using class properties e.g.:
#property (nonatomic, strong) UITableView *tableView1;
#property (nonatomic, strong) UITableView *tableView2;
#property (nonatomic, strong) UITableView *tableView3;
In the delegate methods you can check for the correct tableView e.g.:
if (tableView == self.tableView1) {
// add code for tableView1
} else if (tableView == self.tableView2) {
// add code for tableView2
} else if (tableView == self.tableView3) {
// add code for tableView3
} else {
// unknown tableView
}
You have the tableview reference in each of your delegate methods right? You can find out which tableview you are currently walking through based on that..
Assuming..
IBOutlet UITableView *tableView1;
IBOutlet UITableView *tableView1;
IBOutlet UITableView *tableView1;
Ex:
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
if(tableView == tableView1)
return 1;
if(tableView == tableView2)
return 5;
return 10;
}
You can do the same for the other delegate methods..
I hope I understood your question correctly..
you nedd to create 3 uitableview outlets. and then you can identifies tableviews by specifyin tag. for example tableview1.tag=1, tableview.tag=2 etc.
then in tableview methods you can use it. for example.
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView.tag==1){
return 3;
}
else if(tableView=2)
{return 3;}
}
may be this help.
Swift 4.1
4.1 is a version which i wrote the code. It might be worked in the other version of swift. I'm not sure.
Firstly , right click to the tableViewContent1 and tableViewContent2 and drag it to dataSource and
delegate into View Controller like this image below.
Secondly , you can implement as my code below.
* I've already set the both label in tableViewContent1 and tableViewContent2 with tag = 1000 .
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tableViewContent1: UITableView!
#IBOutlet weak var tableViewContent2: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController :
UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == tableViewContent1 {
// in order to make the tableViewContent1 get 5 rows.
return 5
}
else{
// in order to make the tableViewContent2 get 3 rows.
return 3
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableViewContent1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "content1", for: indexPath) as! TableViewCellFirstCustom
let label : UILabel = cell.viewWithTag(1000) as! UILabel{
lab.text = "to change label in content1."
}
return cell
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "content2", for: indexPath)
let label : UILabel = cell.viewWithTag(1000) as! UILabel
label.text = "to change label in content2."
return cell
}
}
}
after that you will get result like image below.
It worked for me.

Customizing the More menu on a Tab bar

I am using a tab bar (UITabBarController) on my app and I wish to customize the appearance of the table that appears when you click the more button.
I have worked out how to change the appearance of the Navigation bar that is on the more screen by setting
self.moreNavigationController.navigationBar.barStyle
in a subclass of UITabBarController and I have managed to change the background colour of the table by modifying
self.moreNavigationController.topViewController.view.backgroundColor
, but I cannot work out how to change the font colour in the cells that appear on the table.
I was hoping I could use
self.moreNavigationController.topViewController.view.visibleCells
but this always seems to be empty. I've tried doing this in viewDidLoad, viewWillAppear and viewDidAppear with no success. The object self.moreNavigationController.topViewController is of type UIMoreListController, which seems to be undocumented and I can't see anything obvious in the interface that will help me.
Any ideas?
Following on from Stephan's suggestion to replace the dataSource of the moreNavigationController, here is a quick over view of the code I implemented.
I created a new class called MoreTableViewDataSource which implements the UITableViewDataSource protocol. The controller which the more page actually uses to build the table is called the UIMoreListControllerModern, and this implements just the required parts of the UITableViewDataSource protocol. My implementation looks like this.
-(MoreTableViewDataSource *) initWithDataSource:(id<UITableViewDataSource>) dataSource
{
self = [super init];
if (self)
{
self.originalDataSource = dataSource;
}
return self;
}
- (void)dealloc
{
self.originalDataSource = nil;
[super dealloc];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [originalDataSource tableView:table numberOfRowsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [originalDataSource tableView:tableView cellForRowAtIndexPath:indexPath];
cell.textColor = [UIColor whiteColor];
return cell;
}
and then in my CustomTabBarController class I override viewDidLoad as follows:
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *moreController = self.moreNavigationController;
moreController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]])
{
UITableView *view = (UITableView *)moreController.topViewController.view;
view.backgroundColor = [UIColor blackColor];
moreTableViewDataSource = [[MoreTableViewDataSource alloc] initWithDataSource:view.dataSource];
view.dataSource = moreTableViewDataSource;
}
}
As requested here are the header files
#interface MoreTableViewDataSource : NSObject <UITableViewDataSource>
{
id<UITableViewDataSource> originalDataSource;
}
#property (retain) id<UITableViewDataSource> originalDataSource;
-(MoreTableViewDataSource *) initWithDataSource:(id<UITableViewDataSource>) dataSource;
#end
and
#import "MoreTableViewDataSource.h"
#interface CustomTabBarController : UITabBarController
{
MoreTableViewDataSource *moreTableViewDataSource;
}
visibleCells is populated only after the moreNavigationController is displayed.
And the cells are created at runtime, so even if you change the content of the cells, they are replaced when they are displayed.
One thing to try would be to replace the datasource of the moreNavigationController tableView, call the cellForRowAtIndexPath of the original datasource and change its content before returning it.
Using the code below, after having displayed once the moreNavigationController to initialize it, you'll see that when you return to the moreNavigationController, the cells are red, but return immediately to white background.
UITableView *view = (UITableView *)self.tabBarController.moreNavigationController.topViewController.view;
if ([[view subviews] count]) {
for (UITableViewCell *cell in [view visibleCells]) {
cell.backgroundColor = [UIColor redColor];
}
}
Thanks to Unknown.
Following his solution, I will put his code in Swift.
Only what you should do more is create MoreTableViewCell class and just it. You don't have to use Storyboard. If you want to modify tableView you can do it in customizeMoreTableView method.
class TabBarMenuController: UITabBarController, UITableViewDelegate, UITableViewDataSource{
var tabBarItems: [UIViewController] = []
var areMessagesVisible: Bool = false
var titleForTabBars: [String] = ["resources", "events", "training", "my profile", "news", "contacts"]
var iconNames: [String] = ["film", "calendar", "classroom", "profile", "news", "Phone"]
var controllersStoryboardId: [String] = ["resourcesNavController", "eventsNavController", "enablementNavController", "profileNavController", "newsNavController", "contactsNavController"]
// to manage moreTableView
var moreTableView: UITableView = UITableView()
var currentTableViewDelegate: UITableViewDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.customizeMoreTableView()
//to REMOVE
areMessagesVisible = true
if !areMessagesVisible{
self.titleForTabBars.removeAtIndex(4)
self.controllersStoryboardId.removeAtIndex(4)
self.iconNames.removeAtIndex(4)
}
for i in 0 ..< controllersStoryboardId.count{
tabBarItems.append(UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier(controllersStoryboardId[i]) as? UINavigationController ?? UINavigationController())
}
self.moreNavigationController.navigationBar.tintColor = UIColor.blackColor()
}
override func viewWillAppear(animated: Bool) {
for i in 0 ..< tabBarItems.count{
tabBarItems[i].tabBarItem = UITabBarItem(title: titleForTabBars[i], image: UIImage(named: iconNames[i]), selectedImage: UIImage(named: iconNames[i]))
}
self.viewControllers = tabBarItems
}
func customizeMoreTableView(){
moreTableView = self.moreNavigationController.topViewController!.view as? UITableView ?? UITableView()
currentTableViewDelegate = moreTableView.delegate;
moreTableView.delegate = self
moreTableView.dataSource = self;
moreTableView.registerClass(MoreTableViewCell.self, forCellReuseIdentifier: "MoreTableViewCell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let moreCell = tableView.dequeueReusableCellWithIdentifier("MoreTableViewCell", forIndexPath: indexPath) as? MoreTableViewCell ?? MoreTableViewCell()
moreCell.textLabel?.text = titleForTabBars[indexPath.row + 4]
moreCell.imageView?.image = UIImage(named: iconNames[indexPath.row + 4])
/*let testLabel: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
testLabel.backgroundColor = UIColor.yellowColor()
moreCell.addSubview(testLabel)
*/
return moreCell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titleForTabBars.count - 4
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
currentTableViewDelegate?.tableView!(tableView, didSelectRowAtIndexPath: indexPath)
}
}
I followed Ian's implementation to customize the More menu, but I was having a problem retaining the customizations after a memory warning. didReceiveMemoryWarning seems to destroy the UITableView, and when it is regenerated it gets its old dataSource back. Here's my solution:
I replace viewDidLoad on the CustomTabBarController with this:
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController* moreController = self.moreNavigationController;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]]) {
moreController.delegate = self;
self.moreControllerClass = [moreController.topViewController class];
UITableView* view = (UITableView*) moreController.topViewController.view;
self.newDataSource = [[[MoreDataSource alloc] initWithDataSource:view.dataSource] autorelease];
}
}
As you can see, I added a few properties for storing things I needed. Those have to be added to the header and synthesized. I also made CustomTabBarController a UINavigationControllerDelegate in the header. Here's the delegate function I added:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController isKindOfClass:self.moreControllerClass]) {
UIView* view = self.moreNavigationController.topViewController.view;
if ([view isKindOfClass:[UITableView class]]) {
UITableView* tview = (UITableView*) view;
tview.dataSource = self.newDataSource;
tview.rowHeight = 81.0;
}
}
}
This way I make sure my custom data source is always used, because I set it that way just prior to showing the UIMoreListController, every time it's shown.
#interface TabBarViewController () <UITableViewDelegate,UITableViewDataSource>
#property (nonatomic,strong) UITableView* tabBarTableView;
#property (nonatomic,weak) id <UITableViewDelegate> currentTableViewDelegate;
#end
#implementation TabBarViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self costumizeMoreTableView];
}
-(void)costumizeMoreTableView{
_tabBarTableView = (UITableView *)self.moreNavigationController.topViewController.view;
_currentTableViewDelegate = _tabBarTableView.delegate;
_tabBarTableView.delegate = self;
_tabBarTableView.dataSource = self;
[_tabBarTableView registerNib:[UINib nibWithNibName:#"MoreTabBarTableViewCell" bundle:nil] forCellReuseIdentifier:#"MoreTabBarTableViewCell"];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 120;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MoreTabBarTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MoreTabBarTableViewCell" forIndexPath:indexPath];
[cell setMoreTableValues];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
[_currentTableViewDelegate tableView:tableView didSelectRowAtIndexPath:indexPath];
}
#end
This works for me in iOS 13, Swift 5.1:
extension MyTabBarController: UITabBarControllerDelegate {
// handle a select of the More tab
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
// style all the tab bar windows and the More tab bar tableview
if viewController == moreNavigationController,
let moreTableView = moreNavigationController.topViewController?.view as? UITableView {
view.tintColor = .systemOrange
moreNavigationController.navigationBar.tintColor = .systemOrange
moreTableView.tintColor = .systemOrange
moreTableView.backgroundColor = UIColor(named: "Your Color")
moreTableView.visibleCells.forEach {
$0.backgroundColor = UIColor(named: "Your Color")
}
}
}
}
I think I found an easier solution... Just drop this extension on your landing page of Tab Bar Controller. This function is setting the menu tableView after the menu is created and the cells are all in tableView.visibleCells
extension UINavigationController: UINavigationControllerDelegate {
open override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if (viewController.classForCoder.description().description == "UIMoreListController") {
if let moreTableView = tabBarController!.moreNavigationController.topViewController?.view as? UITableView {
for cell in moreTableView.visibleCells {
cell.backgroundColor = .red
}
}
}
}
}

Resources