how to hide side menu when tapped anywhere outside - ios

i want to hide the side menu whenever the user taps anywhere outside. The menu is appearing but i can't find any way to come out of it. any suggestions regarding hidesOnTap will also be appreciated. I have also used a table view to display side menu contents, whenever user taps on any option it gets redirected to that page. How to hide the menu without making any selection. Below is the code
#import "MainMenuViewController.h"
#import "UIImageView+AFNetworking.h"
#import "ProfileViewController.h"
#import "ChatMenuHomeVC.h"
#interface MainMenuViewController ()
{
NSString *username;
NSString *profilestr;
}
#property (nonatomic, weak) IBOutlet UITableViewCell *cellMain;
#end
#implementation MainMenuViewController
#synthesize lblUserName,profilePic;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
//SideMenuToProfileView
arrOfOptions = [[NSMutableArray alloc]init];
[self addTitle:#"Home" imageName:#"icon-sidemenu-home.png" segueName:#"slidingToHome"];
[self addTitle:#"My Chat" imageName:#"icon-sidemenu-chat.png" segueName:#"ChatHomeVc"];
[self addTitle:#"Invite Friends" imageName:#"icon-sidemenu-invite.png" segueName:#""];
[self addTitle:#"Settings" imageName:#"icon-sidemenu-setting.png" segueName:#"slidingToSettings"];
[super viewDidLoad];
UITapGestureRecognizer *tapAction1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(profileVC:)];
tapAction1.numberOfTapsRequired = 1;
profilePic.userInteractionEnabled = YES;
[profilePic addGestureRecognizer:tapAction1];
username = [[NSUserDefaults standardUserDefaults]
stringForKey:#"UserName"];
profilestr = [[NSUserDefaults standardUserDefaults] stringForKey: #"UserProfilePic"];
self.lblUserName.text = username;
[profilePic setImageWithURL:[NSURL URLWithString:profilestr] placeholderImage:[UIImage imageNamed:#"user"]];
self.profilePic.layer.cornerRadius = self.profilePic.frame.size.width / 2;
self.profilePic.clipsToBounds = YES;
// Do any additional setup after loading the view.
}
-(void)addTitle:(NSString *)title imageName:(NSString *)imageName segueName:(NSString *)segue
{
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
[dic setObject:title forKey:#"title"];
[dic setObject:imageName forKey:#"image"];
[dic setObject:segue forKey:#"segue"];
[arrOfOptions addObject:dic];
}
- (void)profileVC:(UITapGestureRecognizer *)tapGesture
{
[self performSegueWithIdentifier:#"SideMenuToProfileView" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"SideMenuToProfileView"])
{
ProfileViewController *destViewController = segue.destinationViewController;
destViewController.senderStr = #"fromUserSideMenu";
}
}

create a background View with size equal to the device in width and height. Add tap gesture recognizer to the view and hide side menu when the view is tapped. Or you can also use a button to get the same functionality writing the code in button action method.
Do as follows
var backgroundView : UIView = UIView()
func createBackgroundView()
{
backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: ScreenSize.SCREEN_WIDTH, height: ScreenSize.SCREEN_HEIGHT))
backgroundView.tag = 10
backgroundView.isHidden = true
}
You can unhide the background view when side menu appears

Related

How to pass an object in a segue rather that a detail of an object?

I have a simple notes app where I have just 2 view controllers:
table view controller - to list all the notes.
view controller - to create new notes.
In the table view controller I have a segue from a cell back to the creation page where a user can edit the note in this specific cell.
But my problem is that when I'm preforming editing to a certain cell(note) I'm creating a new note with the content of what I edited...
So instead of passing the note content in the prepareForSegue method I need to pass the note object...
How can I do that?
this are my classes:
NMNote: (correctly just containing a property of *content, will add more behaviour later)
#import <Foundation/Foundation.h>
#interface NMNote : NSObject
#property (strong, nonatomic) NSString *content;
#end
NMCreateNotesViewController.h:
#import <UIKit/UIKit.h>
#import "NMNote.h"
#interface NMCreateNotesViewController : UIViewController
#property (strong, nonatomic) NMNote *note;
#property (weak, nonatomic) IBOutlet UITextView *textField;
#property (strong, nonatomic) NSString *passedInString;
#end
NMCreateNotesViewController.m:
#import "NMCreateNotesViewController.h"
#import "NMNotesListViewController.h"
#interface NMCreateNotesViewController () <UITextViewDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
#end
#implementation NMCreateNotesViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// listen for keyboard hide/show notifications so we can properly adjust the table's height
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
#pragma mark - Notifications
- (void)adjustViewForKeyboardReveal:(BOOL)showKeyboard notificationInfo:(NSDictionary *)notificationInfo
{
// the keyboard is showing so ƒ the table's height
CGRect keyboardRect = [[notificationInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration =
[[notificationInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.textField.frame;
// the keyboard rect's width and height are reversed in landscape
NSInteger adjustDelta = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? CGRectGetHeight(keyboardRect) : CGRectGetWidth(keyboardRect);
if (showKeyboard)
frame.size.height -= adjustDelta;
else
frame.size.height += adjustDelta;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.textField.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
[self adjustViewForKeyboardReveal:YES notificationInfo:[aNotification userInfo]];
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
[self adjustViewForKeyboardReveal:NO notificationInfo:[aNotification userInfo]];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.saveButton) return;
if (self.textField.text.length > 0) {
self.note = [[NMNote alloc] init];
self.note.content = self.textField.text;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.passedInString != nil) {
self.textField.text = self.passedInString;
}
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
NMNotesListViewController.h:
#import <UIKit/UIKit.h>
#interface NMNotesListViewController : UITableViewController
- (IBAction) unwindToList: (UIStoryboardSegue *) segue;
#end
NMNotesListViewController.m:
#import "NMNotesListViewController.h"
#import "NMCreateNotesViewController.h"
#interface NMNotesListViewController ()
#property (strong, nonatomic) NSMutableArray *notes;
#end
#implementation NMNotesListViewController
- (IBAction) unwindToList: (UIStoryboardSegue *) segue
{
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (note != nil) {
[self.notes addObject:note];
[self.tableView reloadData];
}
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.notes = [[NSMutableArray alloc] init];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (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 [self.notes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NotesPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NMNote *note = [self.notes objectAtIndex:indexPath.row];
cell.textLabel.text = note.content;
return cell;
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell *)sender
{
if ([[segue identifier] isEqualToString:#"noteSegue"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NSInteger indx = [self.tableView indexPathForCell:sender].row;
NMNote *note = self.notes[indx];
destination.passedInString = note.content;
}
}
//#pragma mark - delegate
//
//- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//{
//
//}
#end
This is the screens flow:
the initiate view is this table view:
Now there is the TextView where you write the note:
Now, after you save a note, you go back to the first screen. and then you can tap on a populated cell and you will segue back to this screen (the one with the TextView) so you can edit it. But instead of editing it, it will create a new one with the edited content. like this:
Please, would appreciate any help here to accomplish my task..
Thanks!
The thing you need to do when you pass the note to the NMCreateNotesViewController, is to differentiate between an edit and an add action so when you came back to the table view, you can either replace the old entry with the new edited one, or add a new entry.
The way I would approach this is to have two segues, one from the + button (I'll call it "addSegue") and one from the table view cell (call it "editSegue"). I would also create a property in the list controller to hold the value of the edited row, or set it to something like -1 to indicate it's a new note. Something like this,
#property (nonatomic) NSInteger editedRow;
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"editSegue"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NSInteger indx = [self.tableView indexPathForCell:(UITableViewCell *)sender].row;
self.editedRow = index;
NMNote *note = self.notes[indx];
destination.note = note;
}else if ([segue.identifier isEqualToString:#"addSegue"]) {
self.editedRow = -1;
}
The prepareForSegue method in the NMCreateNotesViewController would be the same as you have in your question. You can get rid of the passedInString property since we're passing in the entire note object instead. In the unwind method in the list controller, you would do this,
- (IBAction) unwindToList: (UIStoryboardSegue *) segue {
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (note != nil && self.editedRow == -1) {
[self.notes addObject:note];
}else{
[self.notes replaceObjectAtIndex:self.editedRow withObject:note];
}
[self.tableView reloadData];
}
in NMCreateNotesViewController.h:
#property (strong, nonatomic) NMNote *note;
#property BOOL adding;
#property (strong,nonatomic) NSString *originalContent;
Then in your NMNotesListViewController.m prepareForSegue
destination.note=self.notes[indx];
destination.adding=NO; // set adding to yes if you are adding a new note
and in your unwind
- (IBAction) unwindToList: (UIStoryboardSegue *) segue
{
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (source.adding && note != nil) {
[self.notes addObject:note];
[self.tableView reloadData];
}
}
in NMCreateNotesViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// listen for keyboard hide/show notifications so we can properly adjust the table's height
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
if (self.note != nil)
{
self.originalContent=self.note.content;
self.textField.text=self.note.content;
}
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.saveButton)
{
if (self.note != nil)
{
self.note.content=self.originalContent;
}
}
else
{
if (self.note == nil)
{
if (self.textField.text.length > 0) {
self.note = [[NMNote alloc] init];
}
self.note.content = self.textField.text;
}
}

How to to create a segue to push back to editing mode from a table view?

Maybe I didn't ask it right in the title, sorry for this, i'm a beginner so I will explain myself:
I have 2 screens:
1. Create notes - this screen have a view controller, TextView and navigation(with create/cancel).
2. Notes page - this screen have a table view controller and a navigation with a plus button.
(very similar to apple notes app)
I want that in the table view, whenever I click a cell it will take me back to the editable page of this note...
So I added a push segue from the cell to the notes page, and every time I'm clicking on a cell it opens a NEW note page...
So I know i'm missing something here and would really appreciate if you can help me figure it out
This is my table view controller .m file:
#import "NMNotesListViewController.h"
#import "NMCreateNotesViewController.h"
#interface NMNotesListViewController ()
#property (strong, nonatomic) NSMutableArray *notes;
#end
#implementation NMNotesListViewController
- (IBAction) unwindToList: (UIStoryboardSegue *) segue
{
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (note != nil) {
[self.notes addObject:note];
[self.tableView reloadData];
}
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.notes = [[NSMutableArray alloc] init];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (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 [self.notes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NotesPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NMNote *note = [self.notes objectAtIndex:indexPath.row];
cell.textLabel.text = note.content;
return cell;
}
#end
And this is my view controller (create notes) .m file:
#import "NMCreateNotesViewController.h"
#interface NMCreateNotesViewController ()
#property (weak, nonatomic) IBOutlet UIBarButtonItem *createButton;
#property (weak, nonatomic) IBOutlet UITextView *textField;
#end
#implementation NMCreateNotesViewController
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWasShown:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = self.textField.superview.frame;
bkgndRect.size.height += kbSize.height;
[self.textField.superview setFrame:bkgndRect];
[self.textField setContentOffset:CGPointMake(0.0, self.textField.frame.origin.y-kbSize.height) animated:YES];
}
- (void) keyboardWillBeHidden: (NSNotification *) aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.textField.contentInset = contentInsets;
self.textField.scrollIndicatorInsets = contentInsets;
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.createButton) return;
if (self.textField.text.length > 0) {
self.note = [[NMNote alloc] init];
self.note.content = self.textField.text;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#jeely was close but what you need to do is , create a segue from viewController to viewController.
In the tableView delegate didSelectRowAtIndexPath you would preform the segue:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:#"yourSegue" sender:sender];
}
Because you want to pass the note to the next controller you will need to do that in the prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"yourSegue"])
{
//get the note
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NMNote *note = [self.notes objectAtIndex:indexPath.row];
//set the note
NMCreateNotesViewController *createVC = (NMCreateNotesViewController*)segue.destinationViewController;
createVC.noteToDisplay = note.content;
}
}
Finally noteToDisplay is just an NSString property that you will set to the textView property once the segue is performed.

Items in view not appearing on load

I want to load another view when I click on one of my UITableCell view, but none of the things that are on the xib file (associated with that view) are showing.
This is how I'm initializing the view (in the controller that generates the tableView):
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = #"Cards";
self.detailController = [[BasicCardViewController alloc] initWithNibName: #"CardView" bundle:nil];
}
return self;
}
This is where I deal with the selection:
- (void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *component = self.resultsTuples[indexPath.row];
[AJAXUtils getAsyncJsonWithUrl:(NSURL *)[NSURL URLWithString:someUrl] callback:^(NSDictionary *returnjson) {
if (returnjson != nil) {
NSString *userPageLink = returnjson[#"Node"][#"SessionInfo"][#"PostingAs"][#"Key"];
self.detailController.userPageLink = userPageLink;
self.detailController.nodePage = returnjson[#"Node"][#"Key"];
NSString *selectedCard = component[#"$element"][#"Title"];
[self.detailController setDescription:component[#"element"][#"ContactCard"][#"Description"]];
[self.detailController setPageTitle:selectedCard];
self.detailController.title = selectedCard;
NSString* rating = component[#"$element"][#"Summary"][#"AverageRating"];
self.detailController.rating =(NSInteger)rating;
[self.navigationController pushViewController:self.detailController animated:YES];
}
}];
}
This is my BasicCardView code -
#implementation BasicCardViewController
#synthesize userPageLink = _userPageLink;
#synthesize nodePage = _nodePage;
- (void)viewDidLoad {
_trendingImageView.image = [UIImage imageNamed:#"trending.png"];
}
- (UILabel *)label {
return (id)self.view;
}
- (void)loadView {
self.rateView = [[RateView alloc] init];
}
- (void)setDescription:(NSString *)description {
_description = description;
_descriptionView.text = description;
}
- (void)setPageScore:(NSString *)pageScore {
_pageScore = pageScore;
_pageScoreLabel.text = pageScore;
}
- (void)setRestaurantImage:(UIImage *)restaurantImage {
_restaurantImage.image = restaurantImage;
}
- (void)setPageTitle:(NSString *)title {
_pageTitle = title;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
self.rateView.notSelectedStar =[UIImage imageNamed:#"kermit_empty.png"];
self.rateView.halfSelectedStar = [UIImage imageNamed:#"kermi_half.png"];
self.rateView.fullSelectedStar = [UIImage imageNamed:#"kermit_full.png"];
self.rateView.rating = self.rating;
self.rateView.editable = YES;
self.rateView.maxRating = 5;
self.rateView.delegate = self;
_pageTitleLabel.text = _pageTitle;
}
Why is nothing appearing when the cell is clicked?
But if I do self.view = rateView in the viewDidLoad, the rateView appears.
The view controller calls loadView method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property. And it appeared as if your self.view is nil, in loadView method, you have created self.rateView but hasn't assigned it to self.view to make it visible.
Maybe the getAsyncJsonWithUrl block called out of the main thread try, to call the pushViewController inside the mainQueue as following:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.navigationController pushViewController:self.detailController animated:YES];
}];
It may help sometimes.
_detailController = [[BasicCardViewController alloc] initWithNibName: #"CardView" bundle:nil];

Placing UIImage at tapped image in UITableViewCell

Currently I have custom UITablViewCell's (BIDSelectBusinessCustomCell) that are displayed in a tableView (myTableView). The custom cell is made up of a UIImageView and a label. When the view loads the labels are populated with the strings from my model. UIImageViews are blank. I want to be able for a user to 'tap' the UIImageView, select a picture from what is stored on their phone and for that image to be saved to the UIImageView.
From the below code I can get the 'tap' gesture, then the pickercontroller pops up and a user selects an image. The way the code is now one image that is selected is set for all of the UIImageViews. Which is understandable. But I want it to be set to that particular UIImageView and don't know how to.
Code:
#import <UIKit/UIKit.h>
#interface BIDBusinessSelectViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UIGestureRecognizerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
#property (strong, nonatomic) NSArray *linkedBusinessParseArray;
//Stores the array of models
#property (strong, nonatomic) NSMutableArray *linkedBusinessParseModelArray;
#property NSUInteger relevantIndex;
#property (strong, nonatomic) UIImage *tempImageHolder;
#end
#import "BIDBusinessSelectViewController.h"
#import <Parse/Parse.h>
#import "BIDBusinessModel.h"
#import "BIDSelectBusinessCustomCell.h"
#interface BIDBusinessSelectViewController () <ImageSelect>
{
BIDSelectBusinessCustomCell *aCell;//define a cell of ur custom cell to hold selected cell
UIImage *choosenImage; //image to set the selected image
}
#end
#implementation BIDBusinessSelectViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
self.linkedBusinessParseModelArray = [[NSMutableArray alloc]init];
//create query
PFQuery *linkedBusinessParseQuery = [PFQuery queryWithClassName:#"linkedBusinessParseClass"];
//follow relationship
[linkedBusinessParseQuery whereKey:#"currentBusinessUserParse" equalTo:[PFUser currentUser]];
[linkedBusinessParseQuery whereKey:#"linkRequestSentParse" equalTo:#"Approved"];
[linkedBusinessParseQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
self.linkedBusinessParseArray = objects; //store them in my model array
//loop through model array from Parse
for (NSDictionary *dict in self.linkedBusinessParseArray) {
NSString *descPlaceNameParse = [dict objectForKey:#"placeDescriptionParse"];
NSLog(#"descPlacesNameParse: %#",descPlaceNameParse);
PFObject *tempObj = (PFObject *) dict;
NSString *tempObjString = tempObj.objectId;
NSLog(#"tempObjString (inside dict): %#", tempObjString);
//storing values from Parse into my model
BIDBusinessModel *userModel = [[BIDBusinessModel alloc]init];
userModel.descriptionModelParse = descPlaceNameParse;
userModel.objectIdModelParse = tempObjString;
[self.linkedBusinessParseModelArray addObject:userModel];
NSLog(#"self.linkedBusinessParseModelArray: %lu", (unsigned long)[self.linkedBusinessParseModelArray count]);
//Reload tableview. Has to go here in block otherwise it does not occur
[self.myTableView reloadData];
}
}];
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Device has no camera"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[myAlertView show];
}
choosenImage = [UIImage imageNamed:#"pin.png"]; //hear u need to set the image for cell assuming that u are setting initially same image for all the cell
}
#pragma mark -
#pragma mark Table Delegate Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.linkedBusinessParseModelArray.count; //returns count of model NSMutableArray
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Start cellforRowStIndex");
static NSString *CellIdentifier = #"Cell";
BIDSelectBusinessCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[BIDSelectBusinessCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
BIDBusinessModel *bizModel;
bizModel = self.linkedBusinessParseModelArray[indexPath.row];
bizModel.image = choosenImage;
//cell.descLabel.text = [NSString stringWithFormat:#"bid= %d",indexPath.row];//set text from the model//Omitted for my desc
cell.descLabel.text = bizModel.descriptionModelParse;
cell.logoImage.image =bizModel.image; //setting the image initially the image when u set in "viewDidLoad" method from second time onwords it will set from the picker delegate method
//insted of settig the gesture hear set it on the custom cell
cell.ImageSelectDelegate = self; //setting the delegate
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
// hear implementation of delegate method
- (void)selectSetImageForSelectedLogImage:(UIImageView *)logoImgView;
{
//open up the image picker
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
aCell = (BIDSelectBusinessCustomCell *)logoImgView.superview; //her getting the cell
[self presentViewController:picker animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *aChosenImage = info[UIImagePickerControllerEditedImage];
//UIImage holder to transfer to cellForRowAtIndexPath
choosenImage = aChosenImage;
NSIndexPath *indexPath = [self.myTableView indexPathForCell:aCell];
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; //hear reloading the selected cell only not entire tableview
//get the model and set the choosen image
BIDBusinessModel *bizModel;
bizModel = self.linkedBusinessParseModelArray[indexPath.row];
bizModel.image = aChosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#import <UIKit/UIKit.h>
#protocol ImageSelect<NSObject> //for this u need use custom delegate so i did like this
- (void)selectSetImageForSelectedLogImage:(UIImageView *)logoImgView;
#end
#interface BIDSelectBusinessCustomCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *descLabel;
#property (strong, nonatomic) IBOutlet UIImageView *logoImage;
#property (nonatomic, assign) id<ImageSelect>ImageSelectDelegate; // deleagte
#end
#import "BIDSelectBusinessCustomCell.h"
#implementation BIDSelectBusinessCustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.logoImage = [[UIImageView alloc]init];
self.descLabel = [[UILabel alloc]init];
//set up gesture hear in the custom cell insted in the controller class
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapLogoImage:)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[tap setDelegate:self];
self.logoImage.userInteractionEnabled = YES;
[self.logoImage addGestureRecognizer:tap];
//[self addSubview:logoImage];
//[self addSubview:descLabel];
}
return self;}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)tapLogoImage:(UITapGestureRecognizer *)guesture
{
if([self.ImageSelectDelegate respondsToSelector:#selector(selectSetImageForSelectedLogImage:)])
{
[self.ImageSelectDelegate selectSetImageForSelectedLogImage:self.logoImage];//call the delegate method from the selected cell
}
}
#end
Yup for this, i tried but finally i did something like this, go through this u may find some solution. and hope this helps u :)
//in custom cell "BIDSelectBusinessCustomCell.h"
#import <UIKit/UIKit.h>
//define a delegate method that is called each time when u tapped on cell
#protocol ImageSelect<NSObject> //for this u need use custom delegate so i did like this
- (void)selectSetImageForSelectedLogImage:(UIImageView *)logoImgView;
#end
#interface BIDSelectBusinessCustomCell : UITableViewCell <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
{
UIImageView *logoImage; //your image holder
UILabel *descLabel; //label
}
#property (nonatomic, retain) UIImageView *logoImage;
#property (nonatomic, retain) UILabel *descLabel;
#property (nonatomic, assign) id<ImageSelect>ImageSelectDelegate; // deleagte
#end
//in custom cell "BIDSelectBusinessCustomCell.m"
#import "BIDSelectBusinessCustomCell.h"
#implementation BIDSelectBusinessCustomCell
#synthesize logoImage;
#synthesize descLabel;
#synthesize ImageSelectDelegate;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
logoImage = [[UIImageView alloc]init];
descLabel = [[UILabel alloc]init];
//set up gesture hear in the custom cell insted in the controller class
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapLogoImage:)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[tap setDelegate:self];
logoImage.userInteractionEnabled = YES;
[logoImage addGestureRecognizer:tap];
[self addSubview:logoImage];
[self addSubview:descLabel];
}
return self;
}
- (void)dealloc
{
[logoImage release];
[descLabel release];
[super dealloc];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
//in this method simply i am setting the frames of subviews
[super layoutSubviews];
self.logoImage.frame = CGRectMake(130, 2, 44,44 );
self.descLabel.frame = CGRectMake(20, 2, 60, 44);
}
- (void)tapLogoImage:(UITapGestureRecognizer *)guesture
{
if([self.ImageSelectDelegate respondsToSelector:#selector(selectSetImageForSelectedLogImage:)])
{
[self.ImageSelectDelegate selectSetImageForSelectedLogImage:self.logoImage];//call the delegate method from the selected cell
}
}
#end
//in your view controller class u need to do something like this ;)
//ViewController.h file
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (retain, nonatomic) IBOutlet UITableView *aTableView;
#property (nonatomic, retain) NSIndexPath *selectedIndexPath; //no need just try
#end
//in your "ViewController.m" file
#interface ViewController ()<UITableViewDataSource, UITableViewDelegate,UITextFieldDelegate,UIImagePickerControllerDelegate,UINavigationControll erDelegate,ImageSelect>//delegate
{
BIDSelectBusinessCustomCell *aCell;//define a cell of ur custom cell to hold selected cell
UIImage *choosenImage; //image to set the selected image
}
- (void)viewDidLoad
{
[super viewDidLoad];
choosenImage = [UIImage imageNamed:#"Star.png"]; //hear u need to set the image for cell assuming that u are setting initially same image for all the cell
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[aTableView release];
[super dealloc];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4; //pass array check array contains valid objects
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BIDSelectBusinessCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[BIDSelectBusinessCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
BIDBusinessModel *bizModel;
bizModel = self.linkedBusinessParseModelArray[indexPath.row];
bizModel.image = aChosenImage;
cell.descLabel.text = [NSString stringWithFormat:#"bid= %d",indexPath.row];//set text from the model
cell.logoImage.image =bizModel.image; //setting the image initially the image when u set in "viewDidLoad" method from second time onwords it will set from the picker delegate method
//insted of settig the gesture hear set it on the custom cell
cell.ImageSelectDelegate = self; //setting the delegate
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
// hear implementation of delegate method
- (void)selectSetImageForSelectedLogImage:(UIImageView *)logoImgView;
{
//open up the image picker
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
aCell = (BIDSelectBusinessCustomCell *)logoImgView.superview; //her getting the cell
[self presentViewController:picker animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *aChosenImage = info[UIImagePickerControllerEditedImage];
//UIImage holder to transfer to cellForRowAtIndexPath
choosenImage = aChosenImage;
NSIndexPath *indexPath = [aTableView indexPathForCell:aCell];
[self.aTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; //hear reloading the selected cell only not entire tableview
//get the model and set the choosen image
BIDBusinessModel *bizModel;
bizModel = self.linkedBusinessParseModelArray[indexPath.row];
bizModel.image = aChosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
Yes it is true this would set the image to every row..
Now what you can do is : -
While loading of tableViewCells just assign the tag of UIImageView as the (indexPath.Row).
This would assign unique tags to the ImageView.
You can easily get the tag of that imageView while tapping and now you can assign the image to particular imageView through tagValue of that imageView.
This would assign image to a particular imageView as all have unique tags.
Hope you got the answer of your problem.

TableViewCell - DetailtextLabel to call WebViewController

I'm working on RSS app, and in my last view (tableView), i would like to use the cell.detailTextlabel to call the WebViewController and open the related article in Safari.
Actually I don't know if this is the best way, but i need to have this "Read More" to open the whole article.
In the end of my third section (attached image), i inserted the "Read More" - detailTextLabel.text = #"Read More" - but i don't know how to link to the WebViewController and to pass the correct URL.
Searching on the net, i found this example to open in Safari:
**WebViewController.h**
#import <UIKit/UIKit.h>
#interface WebViewController : UIViewController
#property (strong, nonatomic) NSString *url;
#property (strong, nonatomic) UIWebView *webView;
- (id)initWithURL:(NSString *)postURL title:(NSString *)postTitle;
#end
**WebViewController.m**
#implementation WebViewController
#synthesize url = _url, webView = _webView;
- (id)initWithURL:(NSString *)postURL title:(NSString *)postTitle
{
self = [super init];
if (self) {
_url = postURL;
self.title = postTitle;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.url = [self.url stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *newURL = [NSURL URLWithString:[self.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// Do any additional setup after loading the view.
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.webView];
[self.webView loadRequest:[NSURLRequest requestWithURL:newURL]];
}
- (void)viewDidAppear:(BOOL)animated {
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Thanks in advance.
You can add a custom UIButton instance to the tableview cell and tag it with indexPath.row or indexPath.section according to your structure. On the button action, get the sender's tag and get the exact URL out of your dataSource Array and call WenViewController with that URL.
You can add the button in cell's contentView with desired frame. For eg
CGRect cellFrame = cell.contentView.frame;
UIButton *readMore = [[UIButton alloc]
initWithFrame:CGRectMake(cellFrame.origin.x+20, cellFrame.origin.y+cellFrame.size.height - yourButtonHeight -10, yourButtonWidth, yourButtonHeight)];
[readMore addTarget:self action:#selector(openWebView:) forControlEvents:UIControlEventTouchUpInside];
[readMore setTitle:#"Read More" forState:UIControlStateNormal];
[readMore setTag:indexPath.row];
[cell.contentView addSubview:readMore];
// Release readMore button if not using ARC
And then make the method
-(void)openWebView:(UIButton*)sender{
int tag = sender.tag;
// Get URL from array using tag as index
}

Resources