I stumbled upon this git repo in an SO post and was just giving it a trial run. Basically, it's supposed to setup an observer for the volume button on your iphone. I installed it with Cocoapods, and tried the example but wasn't able to detect volume up/down pushes. Below is my code. Does anyone have any experience working with this package? is there something I'm missing?
I'm developing in XCode 7 and tested this on an iPhone 6.
ViewController.h
#import <UIKit/UIKit.h>
#import "JPSVolumeButtonHandler/JPSVolumeButtonHandler.h"
#interface ViewController : UIViewController
#property (weak, nonatomic) JPSVolumeButtonHandler *volumeHandler;
#property (strong, nonatomic) IBOutlet UILabel *outputLabel;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.outputLabel.text = #"";
self.volumeHandler = [JPSVolumeButtonHandler volumeButtonHandlerWithUpBlock:^{
self.outputLabel.text = #" Up! ";
} downBlock:^{
self.outputLabel.text = [self.outputLabel.text stringByAppendingString:#" Down! "];
}];
}
#end
You have a weak reference to JPSVolumeButtonHandler. This means that this property will be released just after assigning to it (or to be more precise, at a point after exiting from viewDidLoad). Just change weak to strong and everything will be working just fine.
Related
I am very new to iOS. I am having some difficulty with a project I am working on for iOS. I believe that this problem should have a simple solution, but I have spent hours looking at tutorials and other submissions on this website, but so far nothing has worked.
My issue is that I have 5 TextFields in ViewControllerS, and I want to take the data from those TextFields, and combine them in a TextView in ViewControllerView. Here is my code.
ViewControllerS.h:
#import <UIKit/UIKit.h>
#interface ViewControllerS : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *txtfDay;
#property (weak, nonatomic) IBOutlet UITextField *txtfMonth;
#property (weak, nonatomic) IBOutlet UITextField *txtfName;
#property (weak, nonatomic) IBOutlet UITextField *txtfStart;
#property (weak, nonatomic) IBOutlet UITextField *txtfEnd;
#property (weak, nonatomic) IBOutlet UIButton *btnFinish;
#end
ViewControllerS.m:
#import "ViewControllerS.h"
#interface ViewControllerS ()
#end
#implementation ViewControllerS
#synthesize txtfDay;
#synthesize txtfMonth;
#synthesize txtfName;
#synthesize txtfStart;
#synthesize txtfEnd;
#synthesize btnFinish;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
}
#end
ViewControllerView.h:
#import <UIKit/UIKit.h>
#interface ViewControllerView : UIViewController
#property (weak, nonatomic) IBOutlet UITextView *txtViewFinal;
#end
ViewControllerView.m:
#import "ViewControllerView.h"
#interface ViewControllerView ()
#end
#implementation ViewControllerView
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
}
#end
Well, as you can see, this is basically just the skeleton of my program. I have made so many changes to this code as I followed tutorials, tried ideas from here, and listened to what my classmates had to say. Nothing has worked so far, but I know it's a simple fix. I am liking the use of NSUserDefaults, but if anyone has any other ideas, I will try them as well. Again, I'm just trying to figure out how to pass data from one ViewController to another with TextFields and a TextView.
I do not need directions for all 5, but rather just 1. I can figure out the formatting and the other 4 if I just get a nudge in the right direction.
THANK YOU FOR ANY ASSISTANCE I MAY RECEIVE! I really do enjoy programming with Xcode, but it's been very frustrating too. Thanks!
It's not working because at create point, your ViewControllerView instance still have not loaded UI components, so even if you pass it directly to the textView, it will be simply ignored at this point.
Create a dictionary at ViewControllerView.h to pass data from ViewControllerS like this:
#property (nonatomic, strong) NSDictionary *dicTextData;
and set the data into it. After doing this, just load this data from within your ViewControllerView's -(void)viewDidLoad and voila !
Update
ViewControllerS.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"ViewControllerView"]) {
ViewControllerView *destination = segue.destinationViewController;
destination.dicTextData = #{#"day":self.txtfDay.text,
#"Month":self.txtfMonth.text,
#"Name":self.txtfName.text}; //and so on...
}
}
ViewControllerView.m
- (void)viewDidLoad {
self.txtViewFinal.text = [NSString stringWithFormat:#"My name is %#", [self.dicTextData objectForKey:#"Name"]];
//and so on...
}
Note that I did't use all fields on my example, but I'm sure you got the point. Good coding!
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"ViewControllerView"]){
ViewControllerView *destination = segue.destinationViewController;
destination.finalText = self.txtfDay.text;
}
Please make sure you set the identifier of the segue correctly.
Edit:
Thanks #rmaddy point out the problem:
For uncoupling purpose, it would be a better way to store the data that you will pass with a property and let the view controller handle that data. In this case let's say there is a NSString type property called finalText. The prepareForSegue method stored the data and now you can handle this data freely.
There are multiple ways for doing this.An alternative way is to use AppDelegate object.Follow the steps-
Write this line in AppDelegate.h file-
#property (nonatomic, strong) NSString *combinedText;
Import the AppDelegate file in your ViewControllerViewS.m file.Such as-
#import "AppDelegate.h"
Write the line in viewDidLoad of ViewControllerViewS.m -
appDelegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
Now write the line in the body of the btnFinish button-
appDelegate.combinedText=[NSString stringWithFormat:#"fDay:%#,fMonth:%#,fName:%#,fStart:%#,fEnd:%#",
self.txtfDay.text, self.txtfMonth.text, self.txtfName.text, self.txtfStart.text, self.txtfEnd.text];
Now in destination ViewController.m file repeat step 2 and 3.
Now assign the combined text value to the textView.Like-
UITextView *textView=[[UITextView alloc]init];
textView.text=appDelegate.combinedText;
Let me know if it works for you.Thank you.
I am not sure what is causing this problem, but I now cannot create outlets. When I create an outlet it appears and works fine in code, but does not appear under the view controller in storyboard. Old outlets have a warning symbol on them like this
When I remove this outlet, its gone and does not appear back to connect. I am running Xcode beta 6.2 because moving to 6.2 temporarily fixed this problem because I was having it beforehand in 6.1.
Here is the .h file of this class
#import <UIKit/UIKit.h>
#interface DashboardViewController : UITableViewController {
NSString *currentDay;
}
#property (nonatomic, weak) IBOutlet UILabel *dayLabel;
#property (nonatomic, weak) IBOutlet UILabel *blockLabel;
#property (nonatomic, weak) IBOutlet UILabel *currentClassLabel;
#end
and here are the outlets listed in storyboard
These are the details of the warning, but this is .h file's code for this class
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface InfoViewController : UIViewController {
IBOutlet UIScrollView *AISScrollView;
IBOutlet MKMapView *AISMapView;
}
-(IBAction)studentHandbook:(id)sender;
#end
Oddly enough, I ended up finding a solution and that was moving the project out of the directory that it was in. It was in my Dropbox folder and moving it out fixed. If anyone has this problem in the future and also happens to have the proj in their Dropbox, move it out.
try to change this:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface InfoViewController : UIViewController {
IBOutlet UIScrollView *AISScrollView;
IBOutlet MKMapView *AISMapView;
}
-(IBAction)studentHandbook:(id)sender;
#end
to that:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface InfoViewController : UIViewController {
}
#property (nonatomic,weak) IBOutlet UIScrollView *AISScrollView;
#property (nonatomic,weak) IBOutlet MKMapView *AISMapView;
-(IBAction)studentHandbook:(id)sender;
#end
Just in case someone suffers from the same thing again, the best answer inside this other thread did the trick for me:
XCode 6: can't connect any IBOutlet to ViewController
Removing the .h and .m files from the project (their references) and readding them again was the solution that worked for me.
I would like to point out that self is a WelcomeViewController and that it inherits from UIViewController :
WelcomeViewController.h
#import <UIKit/UIKit.h>
#interface WelcomeViewController : UIViewController
#property (strong, nonatomic) NSString* score;
#property (strong, nonatomic) NSUserDefaults* preferences;
#end
WelcomeViewController.m
#import "WelcomeViewController.h"
#import "GESceneController.h"
#import <iAd/iAd.h>
#interface WelcomeViewController ()
#property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
#property (weak, nonatomic) IBOutlet UILabel *highScoreLabel;
#end
#implementation WelcomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.canDisplayBannerAds = YES;
[self.scoreLabel setText:self.score];
NSString* highScoreText = [NSString stringWithFormat:#"Meilleur score : %ld",
[self.preferences integerForKey:#"highscore"]];
[self.highScoreLabel setText:highScoreText];
// Do any additional setup after loading the view.
}
and I get the error : [WelcomeViewController setCanDisplayBannerAds:]: unrecognized selector sent to instance 0x7d97f080
Have you imported the iAd file into your linked frameworks and libraries? If not, goto your build info and scroll all the way to the bottom, there you will find 'linked frameworks..' and add the framework into you app.
I wondering if anyone has ever ran into this problem.
This goes back to my other question where people are saying that codes just don't start working suddenly without reason.
I spent hours debugging my app going through every single line of code. It won't run if I launch my app from Xcode, simulator or iPhone. Yet when I launch my app on the iPhone without going through Xcode, it works perfectly.
I tried restarting Xcode and the same thing happened. Any idea what might be causing this?
#import "CardGameViewController.h"
#import "Deck.h"
#import "PlayingCardDeck.h"
#import "PlayingCard.h"
#import "CardMatchingGame.h"
#interface CardGameViewController ()
#property (nonatomic, strong) CardMatchingGame *game;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
#property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
#end
#implementation CardGameViewController
-(CardMatchingGame *)game{
if (!_game) _game = [[CardMatchingGame alloc] initWithCardCount:[self.cardButtons count] usingDeck:[self createDeck]];
return _game;
}
-(Deck *)createDeck{
return [[PlayingCardDeck alloc] init];
}
- (IBAction)touchCardButton:(UIButton *)sender {
NSUInteger chosenButtonIndex = [self.cardButtons indexOfObject:sender];
[self.game chooseCardatIndex:chosenButtonIndex];
[self updateUI];
}
-(void)updateUI{
for (UIButton *cardButton in self.cardButtons){
NSUInteger cardButtonIndex = [self.cardButtons indexOfObject:cardButton];
Card *card=[self.game cardAtIndex:cardButtonIndex];
[cardButton setTitle:[self titleForCard:card] forState:UIControlStateNormal];
[cardButton setBackgroundImage:[self backgroundImageForCard:card] forState:UIControlStateNormal];
cardButton.enabled = !card.isMatched;
self.scoreLabel.text = [NSString stringWithFormat:#"Score: %d", self.game.score];
}
}
-(NSString *)titleForCard:(Card *)card {
return card.isChosen ? card.contents : #"";
}
-(UIImage*) backgroundImageForCard:(Card *)card{
return [UIImage imageNamed:card.isChosen ? #"cardFront" : #"cardBack"];
}
#end
There's a breakpoint at
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
In the debugger, it says -0 [CardGameViewController setCardButtons:]
And all my properties in the console shows up as nil.
You set a breakpoint on this line:
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
While I've never set a breakpoint in this place in my code, I suspect what is happening is that both the setter and the getter are getting breakpoints.
And right before "viewDidLoad" would get called in your "CardGameViewController", that's where the XIB/storyboard would be loaded and the IBOutletCollection of UIButtons would be loaded as well. Hence the breakpoint hitting.
If you turn that breakpoint off, I think you will have much better luck with launching your app on both the device and in the simulator.
I have made a simple app to test this and cannot figure it out. I have an iPad storyboard where I have put two container views as shown below. I have a label in one view and a button in another. My button will increment the label, 1 number at a time.
My problem is not passing the value or incrementing, but getting the view to load the new value.
Each container has its own ViewController
Some code below, although very sparse as Ive written a bunch and deleted as it didn't work. Please help with the correct format. I would like to keep this general format, updating global variable within button and it updating the label.
LabelViewController.h
#import <UIKit/UIKit.h>
#interface LabelViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *checkLabel;
-(void)loadLabel;
#end
LabelViewController.m
#import "LabelViewController.h"
#import "ParentViewController.h"
#interface LabelViewController ()
#end
#implementation LabelViewController
#synthesize checkLabel;
-(void)loadLabel{
checkLabel.text = [NSString stringWithFormat:#"%d",value];
[self.view setNeedsDisplay];
}
- (void)viewDidLoad
{
[self loadLabel];
[super viewDidLoad];
}
ButtonViewController.h
#import <UIKit/UIKit.h>
#interface ButtonViewController : UIViewController
- (IBAction)checkButton:(id)sender;
#end
ButtonViewController.m
#import "ButtonViewController.h"
#import "ParentViewController.h"
#import "LabelViewController.h"
#interface ButtonViewController ()
#end
#implementation ButtonViewController
- (IBAction)checkButton:(id)sender {
value++;
NSLog(#"%d",value);
LabelViewController *fnc = [[LabelViewController alloc] init];
[fnc loadLabel];
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
Picture at:
http://farm4.staticflickr.com/3822/9469907420_746db25b23_b.jpg
In ButtonViewController, you don't want to be alloc init'ing an instance of LabelViewController -- the one that's on screen already exists. Both child view controllers are instantiated just before the parent controller is. So, what you need to do is get a reference to the LabelViewController that's on screen. You can do that with self.parentViewController.childViewControllers[0] (that 0 might have to be 1 -- I don't know which controller is which).
LabelViewController *fnc = self.parentViewController.childViewControllers[0];
[fnc loadLabel];