I haven't found a similar question that could answer my question.
My Question is: Why can't I access a UILabel from another class after the dissmissViewController?
Here is my Code:
ClassA.h:
#interface ClassA : UIViewController {
UILabel *_ErrorLabel;
UIActivityIndicatorView *_acIn1;
}
#property (weak, nonatomic) IBOutlet UILabel *ErrorLabel;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *acIn1;
ClassA.m:
shouldPerformSegue, prepareForSegue and statusBarStyle Methods
ClassB.h:
- (IBAction)dismiss;
ClassB.m:
- (IBAction)dismiss
{
[self dismissViewControllerAnimated:YES completion:^{
ClassA *login = [[ClassA alloc] init];
[[login ErrorLabel] setText:#"Please use login."];
[[login acIn1] stopAnimating];
[[login acIn1] setHidesWhenStopped:YES];
[[login acIn1] setHidden:YES];
}];
}
Here is my Code I really hope somebody can help me: I AM ABOUT TO GIVE UP I DON'T KNOW WHY THIS WON'T WORK!
Thanks for your help.
~Markus
Edit1:
I have a ViewController ClassA that contains two text fields and when you click on login you come to a TabBarController where one tab contains the ClassB ViewController and in the ClassB ViewController there is a logout button --> dismiss and when you click this button you should come to the ClassA ViewController AND the ErrorLabel Text should change.
Complete Class: A --> LoginViewControler.h
#import <UIKit/UIKit.h>
#import "ShowProfileViewController.h"
#interface LoginViewController : UIViewController <ShowProfileViewControllerDelegate> {
UILabel *_ErrorLabel;
UIActivityIndicatorView *_acIn1;
}
#property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
#property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
#property (weak, nonatomic) IBOutlet UILabel *ErrorLabel;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *acIn1;
#end
Complete Class: A --> LoginViewController.m
#import "LoginViewController.h"
#import "NewsNavigationController.h"
#import "TabViewController.h"
#interface LoginViewController () <UITextFieldDelegate>
#end
#implementation LoginViewController
#synthesize usernameTextField;
#synthesize passwordTextField;
#synthesize ErrorLabel;
#synthesize acIn1;
- (void)viewDidLoad
{
[super viewDidLoad];
[usernameTextField setDelegate:self];
[passwordTextField setDelegate:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if([identifier isEqualToString:#"login"])
{
[acIn1 startAnimating];
[acIn1 setHidden:NO];
if([self login]){
return YES;
} else {
[self showErrorMessage:#"Data not correct!"];
[acIn1 stopAnimating];
[acIn1 setHidesWhenStopped:YES];
[acIn1 setHidden:YES];
return NO;
}
}
else {
[acIn1 stopAnimating];
[acIn1 setHidesWhenStopped:YES];
[acIn1 setHidden:YES];
return NO;
}
}
- (void)showErrorMessage:(NSString *)message
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:message
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
- (BOOL)login
{
NSString *usernameS = usernameTextField.text;
NSString *passwordS = passwordTextField.text;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://localhost:8888/login.php?username=%#&password=%#", usernameS, passwordS]]];
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *loginDic = [jsonDictionary objectForKey:#"login"];
NSString *ErrorString = [loginDic objectForKey:#"returnString"];
NSLog(#"[+] Login: %#", ErrorString);
if ([ErrorString isEqualToString:#"Success"]){
ErrorLabel.text = #"Login";
return YES;
}
else {
ErrorLabel.text = ErrorString;
return NO;
}
}
- (void)didDismissViewController
{
[ErrorLabel setText:#"Bitte benutzen Sie den Login."];
[acIn1 stopAnimating];
[acIn1 setHidesWhenStopped:YES];
[acIn1 setHidden:YES];
}
- (void)prepareForSegue:(UIStoryboardSegue *)inSegue sender:(id)inSender
{
if([inSegue.identifier isEqualToString:#"login"])
{
ShowProfileViewController *vc = [[ShowProfileViewController alloc] init];
vc.delegate = self;
TabViewController *tabViewController = inSegue.destinationViewController;
NewsNavigationController *theController = [[tabViewController viewControllers] objectAtIndex:0];
[self presentViewController:vc animated:YES completion:nil];
}
}
#end
Complete Class: B --> ShowProfileViewController.h
#import <UIKit/UIKit.h>
#protocol ShowProfileViewControllerDelegate
- (void)didDismissViewController;
#end
#interface ShowProfileViewController : UIViewController
#property (nonatomic, assign) id<ShowProfileViewControllerDelegate> delegate;
- (IBAction)dismiss;
#end
Complete Class: B --> ShowProfileViewController.m
#import "ShowProfileViewController.h"
#import "LoginViewController.h"
#interface ShowProfileViewController ()
#end
#implementation ShowProfileViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
- (void)viewWillAppear:(BOOL)inAnimated
{
[super viewWillAppear:inAnimated];
}
- (IBAction)dismiss
{
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate didDismissViewController];
}];
}
#end
This doesn't work because inside your completion block, you're creating a new instance of your LoginViewController, and setting its text. What you should be actually doing is setting the text of the existing LoginViewController, that should appear after dismissing ShowProfileViewController
In order to achieve your desired behaviour, you can use the delegation pattern. If you're not familiar with this technique, it'd be very important to learn. It's is used all over the place in iOS and Mac OS X development.
The code below might require some tweaking on your side.
In ShowProfileViewController.h, add before #interface:
#protocol ShowProfileViewControllerDelegate
- (void)didDismissViewController
#end
Also, add the following property declaration to ShowProfileViewController:
#property (nonatomic, assign) id<ShowProfileViewControllerDelegate> delegate;
Then, change LoginViewController.h so it looks like
#import "ShowProfileViewController.h"
#interface LoginViewController : UIViewController <ShowProfileViewControllerDelegate> {
UILabel *_ErrorLabel;
UIActivityIndicatorView *_acIn1;
}
#property (weak, nonatomic) IBOutlet UILabel *ErrorLabel;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *acIn1;
Now, in ShowProfileViewController.m, replace the code in the dismiss method so it looks like the following:
- (IBAction)dismiss
{
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate didDismissViewController];
}];
}
In LoginViewController.m, add the following method:
- (void)didDismissViewController
{
[[self ErrorLabel] setText:#"Please use login."];
[[self acIn1] stopAnimating];
[[self acIn1] setHidesWhenStopped:YES];
[[self acIn1] setHidden:YES];
}
And finally, you need to set the delegate property in you ShowProfileViewController to point to the LoginViewController instance. Find in LoginViewController.m in which part of your code you create and present the ShowProfileViewController View Controller and set the delegate property to self. If you're using storyboards, you should do it inside prepareForSegue:.
ClassA *login = [[ClassA alloc] init];
is creating a completly new instance.Not the one you used for coming to class B
Related
My application has a Facebook Login screen, which after login shows a profile picture, username, email, and logout button.
I am trying to figure out how to link the current users profile picture with a UIView or UIImageView (which ever is more applicable, given I used a UIView called FBProfilePictureView) in the main VC called HomeViewController. Here is the code I have for the LoginViewController that has the FB information asked for and returned. I also have it segue to the HomeViewController once the user info has been entered.
LoginViewController.h:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <FacebookSDK/FacebookSDK.h>
#interface LoginViewController : UIViewController <FBLoginViewDelegate>
#property (weak, nonatomic) IBOutlet FBLoginView *loginButton;
#property (weak, nonatomic) IBOutlet UILabel *lblLoginStatus;
#property (weak, nonatomic) IBOutlet UILabel *lblUsername;
#property (weak, nonatomic) IBOutlet UILabel *lblEmail;
#property (weak, nonatomic) IBOutlet FBProfilePictureView *profilePicture;
#property (strong, nonatomic) IBOutlet UIImageView *loginwallpaper;
#property (strong, nonatomic) IBOutlet UIImageView *loggedinwallpaper;
#property (strong, nonatomic) IBOutlet UIImageView *FBlogin;
#property (strong, nonatomic) IBOutlet UIImageView *FBlogout;
#end
and here is the LoginViewController.m
#import "LoginViewController.h"
#interface LoginViewController ()
- (void)toggleHiddenState:(BOOL)shouldHide;
#end
#implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self toggleHiddenState:YES];
self.lblLoginStatus.text = #"";
self.loginButton.readPermissions = #[#"public_profile", #"email"];
self.loginButton.layer.cornerRadius = 0;
[self.loginButton.layer setBorderWidth:0.0f];
self.loginButton.delegate = self;
// Do any additional setup after loading the view.
}
-(void)toggleHiddenState:(BOOL)shouldHide{
self.lblUsername.hidden = shouldHide;
self.lblEmail.hidden = shouldHide;
self.profilePicture.hidden = shouldHide;
self.loggedinwallpaper.hidden = shouldHide;
self.FBlogout.hidden = shouldHide;
}
-(void)toggleUnhiddenState:(BOOL)shouldShow{
self.loggedinwallpaper.hidden = NO;
}
-(void)loginViewShowingLoggedInUser:(FBLoginView *)loginView{
self.lblLoginStatus.text = #"";
[self toggleHiddenState:NO];
[self toggleUnhiddenState:YES];
}
-(void)loginViewShowingLoggedOutUser:(FBLoginView *)loginView{
self.lblLoginStatus.text = #"";
[self toggleHiddenState:YES];
}
-(void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user{
NSLog(#"%#", user);
self.profilePicture.profileID = user.objectID;
self.lblUsername.text = user.name;
self.lblEmail.text = [user objectForKey:#"email"];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tabcontroller = (UITabBarController *)[storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
[self presentViewController:tabcontroller animated:YES completion:nil];
}
-(void)loginView:(FBLoginView *)loginView handleError:(NSError *)error{
NSLog(#"%#", [error localizedDescription]);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
All of the other questions posted on here have not really helped me - they have been too vague.
If someone could just show me how to connect this profile picture to a UIImageView or UIView in the HomeViewController that would be awesome! I know this is easy and I'm just frustrated that this is giving me such an problem
(I know that I need to use the prepareForSeuge method I am just not sure on the syntax of how to accomplish this.)
It will help you. Go to HomeViewController.xib and here put UIView by dragging it.
Now, select that view and on the right side of XCode click on third tab that is Identity Inspector. Here set the class name as FBProfilePictureView then try.
If you want to diplay image in FBProfilePictureView then
Xib/StoryBoard -> Identity Inspector -> class name -> FBProfilePictureView
-(void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user{
NSLog(#"%#", user);
self.profilePicture.profileID = user.id;
}
If you want to display in imageview
queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
dispatch_async( queue, ^{
// Load UImage from URL
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://graph.facebook.com/%#/picture?width=200&height=200", user.id]];
NSData *data = [NSData dataWithContentsOfURL:url];
// Then to set the image it must be done on the main thread
dispatch_sync( dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:data];
yourImageView.image = image
image = nil;
});
});
So perhaps this is a beginner's mistake and super easy to you guys, but i really do not know how to solve it,really appreciate for any suggestions:
Right Now:
1: I have to ViewController: EnterCommandViewController and DetectionViewController
2: I wrote Delegate protocol in EnterCommandViewController and set DetectionViewController as its delegate.
3: About delegate: I have a inputTextField in the EnterCommandView and a "Save" bar button item on the top toolbar in this view. Once I click the save , current view will be dismissed and return back to DetectionView and show the NSString just entered in the UILabel in DetectionView.
Finally, My question is that Why After I alloc and init a EnterCommandViewController instance , that is enterCVS, the instance is still nil as show in end of my post.
Code:
EnterCommandViewController.h
#import <UIKit/UIKit.h>
#import "RscMgr.h"
#protocol EnterCommandDelegate <NSObject>
#optional
-(void) commandEntered:(NSString*)command;
#end
#interface EnterCommandViewController : UIViewController <RscMgrDelegate,EnterCommandDelegate>
{
RscMgr* rscMgr;
IBOutlet UITextField *inputTextField;
// DetectionViewController* detectionViewController;
// __unsafe_unretained id<EnterCommandDelegate> delegate;
}
-(void)sendMessage:(NSString*)message;
-(id)initWithDelegate:(id)delegateToBe;
- (IBAction)cancelPressed;
- (IBAction)savePressed;
#property (nonatomic,weak) id<EnterCommandDelegate> delegate; //assign replaced
#end
EnterCommandVIewController.m
#import "EnterCommandViewController.h"
#import "DetectionViewController.h"
#interface EnterCommandViewController () <UITextFieldDelegate>
{
#private
BOOL connected;
}
#end
#implementation EnterCommandViewController
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
rscMgr = [[RscMgr alloc] init];
[rscMgr setDelegate:self];
// Do any additional setup after loading the view, typically from a nib.
[inputTextField becomeFirstResponder];
}
-(id)initWithDelegate:(id)delegateToBe{
if(self = [super init]){
delegate = delegateToBe;
}
return self;
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputTextField.delegate = self;
}
-(void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
inputTextField.delegate = nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITextFieldDelegate Methods
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[self sendMessage:textField.text];
textField.text = nil;
return NO;
}
#pragma mark - Serial Tx/Rx Methods Implementation
-(void) sendMessage:(NSString *)message{
if(connected == YES) {
[rscMgr writeString:message];
}
else{
NSLog(#"CableDisconnected!");
NSLog(#"Attempted To Send: %#",message);
}
}
- (IBAction)cancelPressed {
[self dismissViewControllerAnimated:YES completion:^{}];
}
- (IBAction)savePressed {
//is anyone listening
if([[[UIDevice currentDevice]systemVersion] compare:#"7.0" options:NSNumericSearch] != NSOrderedAscending){
NSLog(#"SYStem version > 7.0");
}
if(delegate&&[delegate respondsToSelector:#selector(commandEntered:)]){
NSLog(#"SomeMethod is listening");
[delegate commandEntered:inputTextField.text];
}
[self dismissViewControllerAnimated:YES completion:nil]; //commened: ^{}
}
#pragma mark - RscMgrDelegate Methods Implementation
-(void) cableConnected:(NSString *)protocol{
inputTextField.text = #"cableConnected";
[rscMgr setBaud:9600];
[rscMgr open];
connected = YES;
}
-(void) cableDisconnected{
inputTextField.text = #"cableDisconnected";
connected = NO;
}
-(void) readBytesAvailable:(UInt32)length{}
-(void) portStatusChanged{}
#end
DetectionViewController.h
#import <UIKit/UIKit.h>
#import "EnterCommandViewController.h"
#interface DetectionViewController : UIViewController <EnterCommandDelegate>{
}
- (IBAction)showSettings:(UIBarButtonItem *)sender;
#property (nonatomic, strong) EnterCommandViewController* enterCVC;
#property (nonatomic, strong) IBOutlet UILabel *showReceivedCommand;
#end
DetectionViewController.m
#import <Foundation/Foundation.h>
#import "DetectionViewController.h"
#import "EnterCommandViewController.h"
#implementation DetectionViewController
#synthesize showReceivedCommand;
#synthesize enterCVC;
- (IBAction)showSettings:(UIBarButtonItem *)sender {
}
-(void) viewDidLoad{
[super viewDidLoad];
if(showReceivedCommand){
showReceivedCommand.text=#"Initial text";
NSLog(#"UILAbel in ViewDidload is not nil");
}else {
NSLog(#"UILAbel in viewDidload is nil");
}
enterCVC = [[EnterCommandViewController alloc] init];
if(enterCVC.delegate) NSLog(#"X nil");
[enterCVC setDelegate:self];
}
#pragma mark - EnterCommandDelegate function(s)
-(void)commandEntered:(NSString *)command{
dispatch_async(dispatch_get_main_queue(), ^{
if(showReceivedCommand){
NSLog(#"UILabel is not nil");
}else{NSLog(#"UILabel is nil");}
showReceivedCommand = [[UILabel alloc] init];
NSLog(#"command received: %#",command);
showReceivedCommand.text = command;
[showReceivedCommand setNeedsDisplay];
NSLog(#"text in showReceivedCommand is %#",showReceivedCommand.text);
});
}
#end
I set a break point at DetectionViewController.n --> ViewDidLoad() --> [enterCVC setDelegate:self];
I got:
self DetectionViewController * 0x15c50e850 0x000000015c50e850
UIViewController UIViewController
showReceivedCommand UILabel * 0x15c510650 0x000000015c510650
enterCVC EnterCommandViewController * 0x15c611360 0x000000015c611360
showReceivedCommand UILabel * 0x15c510650 0x000000015c510650
enterCVC EnterCommandViewController * 0x15c611360 0x000000015c611360
UIViewController UIViewController
rscMgr RscMgr * nil 0x0000000000000000
inputTextField UITextField * nil 0x0000000000000000
connected BOOL NO false
delegate id 0x0 0x0000000000000000
enterCVC = [[EnterCommandViewController alloc] init]
Try changing that to....
enterCVC = [[EnterCommandViewController alloc] initWithDelegate:self];
Im following this tutorial:
http://www.raywenderlich.com/1845/ios-tutorial-how-to-create-a-simple-iphone-app-tutorial-part-2
I get the following errors:
1.Property implementation must have its declaration in interface "RWTDetailViewController"
2.Property "data" not found on object of type "id"
Here is my code:
#import "RWTScaryBugDoc.h"
#import "RWTScaryBugData.h"
#import "RWTUIImageExtras.h"
#import "RWTDetailViewController.h"
#interface RWTDetailViewController ()
- (void)configureView;
#end
#implementation RWTDetailViewController
#pragma mark - Managing the detail item
#synthesize picker = _picker;
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
self.rateView.notSelectedImage = [UIImage imageNamed:#"shockedface2_empty.png"];
self.rateView.halfSelectedImage = [UIImage imageNamed:#"shockedface2_half.png"];
self.rateView.fullSelectedImage = [UIImage imageNamed:#"shockedface2_full.png"];
self.rateView.editable = YES;
self.rateView.maxRating = 5;
self.rateView.delegate = self;
if (self.detailItem) {
self.titleField.text = self.detailItem.data.title;
self.rateView.rating = self.detailItem.data.rating;
self.imageView.image = self.detailItem.fullImage;
}
}
- (IBAction)titleFieldTextChanged:(id)sender
{
self.detailItem.data.title = self.titleField.text;
}
#pragma mark UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#pragma mark RWTRateViewDelegate
- (void)rateView:(RWTRateView *)rateView ratingDidChange:(float)rating
{
self.detailItem.data.rating = rating;
}
- (IBAction)addPictureTapped:(id)sender {
if (self.picker == nil) {
self.picker = [[UIImagePickerController alloc] init];
self.picker.delegate = self;
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.picker.allowsEditing = NO;
}
[self presentViewController:_picker animated:YES completion:nil];
}
#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissViewControllerAnimated:YES completion:nil];
UIImage *fullImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
UIImage *thumbImage = [fullImage imageByScalingAndCroppingForSize:CGSizeMake(44, 44)];
self.detailItem.fullImage = fullImage;
self.detailItem.thumbImage = thumbImage;
self.imageView.image = fullImage;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
- (BOOL)shouldAutorotateToInterfaceOrientation
{
return YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
When I move my #synthesize into the interface-declaration, I the the following error: "Illegal interface qualifier"
Can anyone help me?
Here is my .h-file:
#import <UIKit/UIKit.h>
#import "RWTRateView.h"
#interface RWTDetailViewController : UIViewController <UITextFieldDelegate, RWTRateViewDelegate, UIImagePickerControllerDelegate, UINavigationBarDelegate>
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet RWTRateView *rateView;
#property (weak, nonatomic) IBOutlet UITextField *titleField;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (strong, nonatomic) UIImagePickerController *picker;
- (IBAction)addPictureTapped:(id)sender;
- (IBAction)titleFieldTextChanged:(id)sender;
#end
Error description is self explanatory, you need to declare picker as a property in interface(.h) file before you move to implementation(.m) file and synthesize it. However you don't need to synthesize properties anymore but if you do that is also fine.
One more thing, you missed the part from tutorial in which writer has declared this property in .h file already. You can have a look again or add this line to RWTDetailViewController.h
#property (strong, nonatomic) UIImagePickerController *picker;
EDIT
For second error you are declaring detailItem as an object of type id, however writer is using a custom class RWTScaryBugDoc in which he should be having a property named data. That's why you are getting the error as property data doesn't belong to id type. You may want to download the sample code at the end of tutorial and cross check the missing points.
You just need to declare your property first. So in the interface (h file or top of your m file), add:
#property (nonatomic, strong)UIImagePickerController *picker;
The #synthetise need to stay in the implementation.
You declare self.detailItem as Id. Id is no class and so it has no attribute, but you try to access self.detailItem.data.... This is not possible.
I can't help you to fix this, because there are so many logical erros in your code, that 99% of it makes no sense for me.
I'm trying to implement an iCarousel that will pass information on to two other view controllers when an image is chosen. While the iCarousel loads perfectly and transitions to the next VC, the information is not displayed on the new VC.
The approach I chose was to create an NSObject file. I can't simply pass the info from VC to VC since I have several VC's that need the information and I'd prefer not to create a singleton or use AppDelegate if possible.
FYI: I do have a tap gesture recognizer added on top of the UIView that acts as the segue to the next VC if that makes any difference.
I've tried every possible tutorial out there and can't seem to figure out my problem. I just need to display a text label and a picture, which should really be pretty easy. Can someone take a quick glance at my code to see what I'm doing wrong?
My NSObject File:
#import <Foundation/Foundation.h>
#interface Stop : NSObject
#property (nonatomic, strong) NSString *title;
#property (nonatomic, strong) NSString *image;
#end
First ViewController.h (with iCarousel on it):
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "iCarousel.h"
#import "DirectionsViewController.h"
#import "Stop.h"
#interface StopsMenuViewController : UIViewController <iCarouselDataSource, iCarouselDelegate>
#property (strong, nonatomic) IBOutlet iCarousel *carousel;
#property (strong, nonatomic) IBOutlet UILabel *titleLabel;
//Title
#property (nonatomic, strong) NSArray *stopTitles;
#property (nonatomic, strong) NSString *stopChosen;
//Image
#property (nonatomic, strong) NSArray *stopImages;
#property (nonatomic, strong) NSString *imageChosen;
#end
First ViewController.m:
#import "StopsMenuViewController.h"
#interface StopsMenuViewController () {
NSMutableArray *allInfo; }
#end
#implementation StopsMenuViewController
#synthesize titleLabel, carousel, stopImages, stopTitles, stopChosen, imageChosen;
- (void)awakeFromNib {
NSString *myPlist = [[NSBundle mainBundle] pathForResource:#"Chinatown" ofType:#"plist"];
NSDictionary *rootDictionary = [[NSDictionary alloc] initWithContentsOfFile:myPlist];
self.stopImages = [rootDictionary objectForKey:#"StopImages"];
self.stopTitles = [rootDictionary objectForKey:#"StopTitles"];
}
- (void)carouselDidScroll:(iCarousel *)carousel {
[titleLabel setText:[NSString stringWithFormat:#"%#", [self.stopTitles
objectAtIndex:self.carousel.currentItemIndex]]];
}
- (void)dealloc {
self.carousel.delegate = nil;
self.carousel.dataSource = nil;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"toDirections"])
{
DirectionsViewController *dvc = [segue destinationViewController];
int itemId = [self.carousel currentItemIndex];
NSIndexPath *path = [NSIndexPath indexPathForRow:itemId inSection:0];
Stop *current = [allInfo objectAtIndex:path.row];
[dvc setPassInfo:current];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.carousel.type = iCarouselTypeCoverFlow2;
allInfo = [[NSMutableArray alloc] init];
Stop *info = [[Stop alloc] init];
stopChosen = [NSString stringWithFormat:#"%#", [self.stopTitles objectAtIndex:self.carousel.currentItemIndex]];
[info setTitle:stopChosen];
[allInfo addObject:info];
info = [[Stop alloc] init];
self.imageChosen = [NSString stringWithFormat:#"%#", [self.stopImages
objectAtIndex:self.carousel.currentItemIndex]];
[info setTitle:self.imageChosen];
[allInfo addObject:info];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.carousel = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel {
return [self.stopImages count];
}
- (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel {
return 4;
}
- (UIView *)carousel:(iCarousel *)_carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {
if (view == nil)
{
view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.stopImages objectAtIndex:index]]];
}
return view;
}
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index {
DirectionsViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"dvc"];
[self.navigationController pushViewController:dvc animated:YES];
}
#end
Second ViewController.h:
#import <UIKit/UIKit.h>
#import "Stop.h"
#interface DirectionsViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *titleLabel;
#property (strong, nonatomic) IBOutlet UIImageView *imageBox;
#property (nonatomic, strong) Stop *PassInfo;
#property (nonatomic, strong) NSString *stopTitle;
#property (nonatomic, strong) NSString *myStopTitle;
#end
Second ViewController.m:
#import "DirectionsViewController.h"
#interface DirectionsViewController ()
#end
#implementation DirectionsViewController
#synthesize PassInfo;
- (void)viewDidLoad {
[super viewDidLoad];
[self.titleLabel setText:[PassInfo title]];
UIImage *image = [UIImage imageNamed:[PassInfo image]];
[self.imageBox setImage:image];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Instead of
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index {
DirectionsViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"dvc"];
[self.navigationController pushViewController:dvc animated:YES];
}
Use
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index {
[self performSegueWithIdentifier:#"toDirections" sender:self];
}
In your code, you're instantiating the second view controller and presenting it, which is not the same as performing a segue. Therefore the method - prepareForSegue:sender: will not be invoked.
i have a tab bar and navigation controller for my app. whenever i tap the scan tab, it kept throwing me Thread 1: EXC_BAD_ACCESS error on line:
ZXCapture.m
[output ZXQT(setDelegate:)ZXAV(setSampleBufferDelegate:)self
Here is my code:
tab bar:
TestScanViewController *scannerViewController=[[TestScanViewController alloc] initWithNibName:#"TestScanViewController" bundle:nil];
navigationController =[[UINavigationController alloc] initWithRootViewController:scannerViewController];
in the TestScanViewController.h:
#interface TestScanViewController : UIViewController <ZXCaptureDelegate>
#end
in the TestScanViewController.m:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import "TestScanViewController.h"
#interface TestScanViewController ()
#property (nonatomic, strong) ZXCapture* capture;
#property (nonatomic, weak) IBOutlet UILabel* decodedLabel;
#end
#implementation TestScanViewController
#pragma mark - View Controller Methods
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(#"%s",__PRETTY_FUNCTION__);
if (self.capture == nil) {
self.capture = [[ZXCapture alloc] init];
self.capture.delegate = self;
self.capture.rotation = 90.0f;
// Use the back camera
self.capture.camera = self.capture.back;
self.capture.layer.frame = self.view.bounds;;
[self.view.layer addSublayer:self.capture.layer];
[self.view bringSubviewToFront:self.decodedLabel];
}else{
[self.capture start];
[self.view.layer addSublayer:self.capture.layer];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(#"%s",__PRETTY_FUNCTION__);
[self.capture.layer removeFromSuperlayer];
[self.capture stop];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
#pragma mark - Private Methods
- (NSString*)displayForResult:(ZXResult*)result {
}
return [NSString stringWithFormat:#"Scanned!\n\nFormat: %#\n\nContents:\n%#", formatString, result.text];
}
#pragma mark - ZXCaptureDelegate Methods
- (void)captureResult:(ZXCapture*)capture result:(ZXResult*)result {
if (result) {
// We got a result. Display information about the result onscreen.
[self.decodedLabel performSelectorOnMainThread:#selector(setText:) withObject:[self displayForResult:result] waitUntilDone:YES];
// Vibrate
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
}
- (void)captureSize:(ZXCapture*)capture width:(NSNumber*)width height:(NSNumber*)height {
}
#end
just like the examples codes from github:
https://github.com/TheLevelUp/ZXingObjC/blob/master/examples/BarcodeScanner/ViewController.m
I had the same problem. If you are targeting iOS version 6 or higher and using ARC, then the cause of the problem is an incomplete migration to ARC in ZXCapture.m.
Look around line 56 for this code:
#interface ZXCapture ()
#property (nonatomic, assign) dispatch_queue_t captureQueue;
#end
The assign is a leftover from before ARC days. It also causes a compiler warning, which was my clue to the solution.
To solve the problem, change the code into:
#interface ZXCapture ()
#property (nonatomic, strong) dispatch_queue_t captureQueue;
#end