Not sure how to set up a UITableViewController - ios

I created a DetailViewController .h and .m files. Then I created a UITableViewController in the storyboard and connected it to the files I made.
Then I added this code to the DetailViewController.m file:
#import "MasterViewController.h"
#import "DetailViewController.h"
// 1
#import "RageIAPHelper.h"
#import <StoreKit/StoreKit.h>
// 2
#interface MasterViewController () {
NSArray *_products;
}
#end
#implementation MasterViewController
// 3
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"In App Rage";
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(reload) forControlEvents:UIControlEventValueChanged];
[self reload];
[self.refreshControl beginRefreshing];
}
// 4
- (void)reload {
_products = nil;
[self.tableView reloadData];
[[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
if (success) {
_products = products;
[self.tableView reloadData];
}
[self.refreshControl endRefreshing];
}];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// 5
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _products.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
SKProduct * product = (SKProduct *) _products[indexPath.row];
cell.textLabel.text = product.localizedTitle;
return cell;
}
#end
But I get compile errors on lines like this:
self.refreshControl = [[UIRefreshControl alloc] init];
Saying that self.refreshControl is not recognized. But how can that be if the file is a UITableView file?
EDIT:
This is the .h
//
// DetailViewController.h
// entrepreneur
//
// Created by MacOSLion on 8/7/13.
// Copyright (c) 2013 MacOSLion. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface DetailViewController : UITableViewController
#end

I think you have a mistake somewhere...
See, you show us the implementation of :
#implementation MasterViewController
But the definition of :
#interface DetailViewController : UITableViewController
That's why, of course, it can't find refreshControl in MasterViewController : it is a property of UITableViewController, so of your DetailViewController.
Please tell me if it's not clear for you.

Add this to .h
#property (weak, nonatomic) UIRefreshControl *refreshControl;

Related

How to pass data from 2nd viewcontroller to tableviewcontroller using delegates

I have 2 viewcontrollers - one is a tableview and the other is a normal viewcontroller. I want pass data from the second viewcontroller to a tableview controller by using delegates. I have created a delegate and delegatemethod in viewcontroller and implemented delegatemethod in the tableview controller. The problem is that I am getting data to the array but tableview is not reloading. Why?
Can anyone help with this problem? Thanks in advance.
#import "TableViewController.h"
#interface TableViewController ()<name>{
NSMutableArray *data;
}
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
data = [NSMutableArray array];
[self.tableView reloadData];
}
- (IBAction)callingSecondView:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
ViewController *var = [storyboard instantiateViewControllerWithIdentifier:#"vc"];
var.delegate = self;
[self.navigationController pushViewController:var animated:YES];
}
-(void)getdata:(NSString *)name{
[data addObject:name];
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell != nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = [data objectAtIndex:indexPath.row];
return cell;
}
And I am creating delegate a object and protocol in ViewController.h
#import <UIKit/UIKit.h>
#protocol name <NSObject>
-(void)getdata : (NSString *)name;
#end
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *txt;
- (IBAction)done:(id)sender;
#property(nonatomic,retain) id<name> delegate;
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)done:(id)sender {
[delegate getdata:self.txt.text];
[self.navigationController popToRootViewControllerAnimated:YES];
}
#end
I think the first VC don't reloadData because it's not the visible VC. Try reloadData when the VC willAppear.
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
}

Array not being passed from tableview to view controller through Delegate

I am trying to copy the array from tableview controller to view controller. I have checked the code multiple times and it seems to be okay.
//Delegate class
#import <UIKit/UIKit.h>
#protocol Category <NSObject>
#required
-(void) delegateMethodForCategory : (NSMutableArray *) arrayOfCategory;
#end
#interface Categories : UIViewController <UITableViewDelegate,UITableViewDataSource>
#property (nonatomic) id<Category> delegate;
#property (nonatomic,strong) NSArray *sports;
#property (strong, nonatomic) IBOutlet UITableView *tableview;
#property (nonatomic,strong) NSMutableArray *selectedIndexes;
#end
//Delegate methods
#import "Categories.h"
#interface Categories ()
{
NSMutableArray *array ;
}
#end
#implementation Categories
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_sports= [[NSArray alloc] initWithObjects: #"Baseball", #"Soccer", #"Hockey",
#"Other",nil];
}
- (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 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return _sports.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
array = [[NSMutableArray alloc]init];
// Configure the cell...
cell.textLabel.text=[self.sports objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
if([tableView cellForRowAtIndexPath:indexPath].accessoryType==UITableViewCellAccessoryNone)
{ [tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
[array addObject:cellText];
}else if([tableView cellForRowAtIndexPath:indexPath].accessoryType==UITableViewCellAccessoryCheckmark){
[tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryNone;
[array removeObject:cellText];
}
}
- (IBAction)doneButton:(id)sender {
[self.delegate delegateMethodForCategory:array];
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
#import <UIKit/UIKit.h>
#import "Categories.h"
#interface ActivityCreator : UIViewController <UIPopoverPresentationControllerDelegate, Category>
#property (nonatomic) Categories *requestClass;
#property (nonatomic,strong) NSMutableArray *arrayOfSports;
#end
//This class implements delegate
import "ActivityCreator.h"
#interface ActivityCreator ()
#end
#implementation ActivityCreator
- (void)viewDidLoad {
[super viewDidLoad];
[self settingUp];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller{
return UIModalPresentationNone;
}
-(void)settingUp{
_requestClass = [[Categories alloc]init];
self.requestClass.delegate = self;
}
#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 {
if([segue.identifier isEqualToString:#"hubabuba"]){
Categories *pop = (Categories *)segue.destinationViewController;
pop.modalPresentationStyle = UIModalPresentationPopover;
pop.popoverPresentationController.delegate = self;
}
}
-(void) delegateMethodForCategory : (NSMutableArray *) arrayOfCategory {
_arrayOfSports = arrayOfCategory;
NSLog(#"%#",_arrayOfSports);
}
Any guidance where I am doing wrong will be of great help. Have been stuck on this for a while.
The delegate method is not being called at all.
Thanks
Set the delegate of Categories class in prepareForSegue method instead of setting in settingUp method.
Write
pop.delegate = self;
In prepareForSegue method.

View flashes when popToRootViewController

I am having a problem with popToRootViewController. I have a root view A and a table view B. And when a row is selected in the table view I pass a string back to the root view and depending on the string. I change the title of buttons on A.
I have made a very simple version of this and put it on gitHub at this link: https://github.com/spennyf/didSelect_test. I am doing this because it is very hard to explain until you actually run this on your phone of the simulator. And see the flash. I don't know why it is happening or how to fix it. Any help would be greatly appreciated I will also post most of the code below, but if you could see the flash for yourself I think it would help explain the problem. Heres the code:
viewControllerA.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *btn1;
#property (strong, nonatomic) IBOutlet UIButton *btn2;
#property (strong, nonatomic) IBOutlet NSString *object;
#end
viewControllerA.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillAppear:(BOOL)animated {
NSLog(#"object: %#", _object);
if ([_object isEqualToString:#"object1"]) {
[_btn1 setTitle:#"new1" forState:UIControlStateNormal];
}
if ([_object isEqualToString:#"object2"]) {
[_btn2 setTitle:#"new2" forState:UIControlStateNormal];
}
}
#end
tableviewB.m
#import "TableViewController.h"
#import "ViewController.h"
#interface TableViewController () {
NSMutableArray *_objects;
}
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_objects = [[NSMutableArray alloc] init];
NSDictionary *obj1 = [[NSDictionary alloc] initWithObjectsAndKeys:#"object1", #"title", nil];
NSDictionary *obj2 = [[NSDictionary alloc] initWithObjectsAndKeys:#"object2", #"title", nil];
// NSDictionary *obj3 = [[NSDictionary alloc] initWithObjectsAndKeys:#"rpi", #"title", nil];
[_objects addObject:obj1];
[_objects addObject:obj2];
}
#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 _objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
//NSLog(#"%#", _objects);
cell.textLabel.text = [[_objects objectAtIndex:indexPath.row] objectForKey:#"title"];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ViewController *myController = (ViewController *)[self.navigationController.viewControllers objectAtIndex:0];
myController.object = [[_objects objectAtIndex:indexPath.row] objectForKey:#"title"];
[self.navigationController popToRootViewControllerAnimated:YES];
}
#end
Again thanks for the help.
There is no problem with your code. It is intended behavior for UIButtons of type UIButtonTypeSystem to flash when its title is changed.
A simple workaround is to set the type of your buttons to UIButtonTypeCustom.
Edit:
You can change the type of the button in Interface Builder:

Passing via segue, PFObject crash Parse.com

I am lost with segue. I tried to do it through this tutorial.
Everything is working but only one line write me error and I don`t know how to fix it.
Image with error:
TableViewController.h
#import <UIKit/UIKit.h>
#import "Parse/Parse.h"
#import "CustomCell.h"
#import "DetailViewController.h"
#interface TableViewController : UITableViewController <UITableViewDelegate,UISearchDisplayDelegate, UISearchBarDelegate> {
NSArray *colorsArray;
NSArray *searchResults;
}
#property (strong, nonatomic) IBOutlet UITableView *colorsTable;
#property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
#property (strong, nonatomic) IBOutlet UISearchDisplayController *searchBarController;
#end
TableViewController.m
#import "TableViewController.h"
#import "CustomCell.h"
#import "DetailViewController.h"
#interface TableViewController (){
}
#end
#implementation TableViewController
#synthesize colorsTable;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{ if ([segue.identifier isEqualToString:#"displayDetail"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
UINavigationController *nav = [segue destinationViewController];
DetailViewController *detailViewController = (DetailViewController *) nav.topViewController;
detailViewController.exam = object;
}
}
- (void) retrieveFromParse {
PFQuery *retrieveColors = [PFQuery queryWithClassName:#"Hracky1"];
[retrieveColors findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
colorsArray= [[NSArray alloc] initWithArray:objects];
}
[colorsTable reloadData];
}];
[self.colorsTable reloadData];
[self.refreshControl endRefreshing];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(retrieveFromParse)];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl = refreshControl;
[refreshControl addTarget:self action:#selector(retrieveFromParse) forControlEvents:UIControlEventValueChanged];
}
- (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 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return colorsArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"colorsCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *tempObject = [colorsArray objectAtIndex:indexPath.row];;
[cell.imageview setFile: [tempObject objectForKey:#"ImageURL"]];
[cell.imageview loadInBackground];
cell.cellTitle.text = [tempObject objectForKey:#"cellTitle"];
cell.cellDescript.text = [tempObject objectForKey:#"cellDescript"];
return cell;
}
#end
DetailedViewController.h
#import <UIKit/UIKit.h>
#import "Parse/Parse.h"
#interface DetailViewController : UIViewController <UITextViewDelegate>
#property (nonatomic, strong) PFObject *exam;
#property (nonatomic, strong) IBOutlet UITextView *descriptext;
#end
DetailViewcontrolled.m
#import "DetailViewController.h"
#import "Parse/Parse.h"
#import "TableViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];{
self.descriptext.text = [self.exam objectForKey:#"TextView"];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
From what I read from your code it is because you are using a normal UITableViewController. To be able to access the property "self.objects" you have to be using Parse's subclassed UITableViewController called "PFTableViewController". They have included the property "objects".
I can recommend this tutorial to get an understanding of the PFTableViewController
http://www.appcoda.com/ios-programming-app-backend-parse/
If you want it to work without the PFTableView you can do the following:
I can see that you have an array called colorsArray and that you add the Parse objects into that array.
So instead of doing this:
PFObject *object = [self.objects objectAtIndex:indexPath.row];
You can do this:
PFObject *object = [colorsArray objectAtIndex:indexPath.row];
I hope it works out for you!
Along with doing the tutorial which another answer here has suggested, perhaps you ought not to pass the PFObject itself...
Figure out and query whatever text you are trying to show in your detail view controller, retrieve it in the table view controller, then ONLY pass that (instead of a entire PFObject).

How to enable a UI botton in ViewController A upon on row selection in TableViewController B. Both View controllers are nested in TabarController

I have two view controllers in tab bar controller. ViewControllerA has two buttons (MybuttonA and MybuttonB with enabled box unchecked in storyboard). ViewControllerB is a TableViewController. I would like to enable buttons in ViewControllerA upon selecting specific rows in ViewControllerB table.
Greatly appreciate any help...
ViewControllerA.h
#import <UIKit/UIKit.h>
#interface ViewControllerA : UIViewController {
IBOutlet UIButton * MybuttonA;
IBOutlet UIButton * MybuttonB;
}
-(IBAction)mybuttonaction:(id)sender;
#property(strong,nonatomic)UIButton *MybuttonA;
#property(strong,nonatomic)UIButton *MybuttonB;
#end
ViewControllerA.m
#import "ViewControllerA.h"
#interface ViewControllerA ()
#end
#implementation ViewControllerA
#synthesize MybuttonA;
#synthesize MybuttonB;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(IBAction)mybuttonaction:(id)sender{
NSString * link = #"https://google.com";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:link]];
}
ViewControllerB.h
#import <UIKit/UIKit.h>
#import "ViewControllerA.h"
#interface ViewControllerB : UITableViewController{
ViewControllerA *viewcontrollerA;
}
#property (nonatomic, retain) ViewControllerA *viewcontrollerA;
#end
ViewControllerB.m
#import "ViewControllerB.h"
#import "ViewControllerA.h"
#interface ViewControllerB () {
}
#end
#implementation ViewControllerB
#synthesize viewcontrollerA;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"CONTENTS";
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(reload) forControlEvents:UIControlEventValueChanged];
[self reload];
[self.refreshControl beginRefreshing];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{return 1;}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
{return 5;}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat: #"Cell #%d", indexPath.row];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString* value = [tableView cellForRowAtIndexPath:indexPath].textLabel.text;
if ([value isEqual:#"1"]){
viewcontrollerA.MybuttonA.enabled=YES;
}
else if ([value isEqual:#"2"])
{
viewcontrollerA.MybuttonB.enabled=YES;
}
}
else {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
}
#end
In ViewControllerB, add the following line to viewDidLoad:
viewControllerA = [self.tabBarController.viewControllers objectAtIndex:0];
Then, the rest of your code should work as you have it.
Note that you should generally use self.viewControllerA instead of accessing the iVar directly unless you have a good reason for it. :-)

Resources