So i am using xcode 6.2 and i am starting with making apps.
but i have a question: whenever i drag something in my storyboard like a navigation bar the map overlays it, it simply won't show up, please help.
Here is my code
#import "ViewController.h"
#interface ViewController () {
GMSMapView *mapView;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:43.642510 longitude:-79.387038 zoom:12 bearing:0 viewingAngle:0];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView.myLocationEnabled = YES;
self.view = mapView;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(43.642510, -79.387038);
marker.title = #"CN-Tower";
marker.snippet = #"A beautifull tower";
marker.map = mapView;
marker.opacity = 0.7;
}
Thanks anyway,
JP
When you do self.view = mapView you're setting the root view of the view controller to the map - and so the map covers everything, replacing whatever you designed in your storyboard.
What you need to do is add the map as a subview of the root view, eg here's a few ways to do it:
Using the Google Maps SDK in views other than the main view
Google Maps iOS SDK - Add UIView/UIButton over a GMSMapView
Google Maps iOS SDK and storyboards
Related
I have an example of animations fully working for OS X, start, pause, change speed etc.
Now I started porting this to iOS and can't even start the animation. I simplified the code to a minimum - it works in OS X, but not on iOS.
What I do is
Show a scene with a (animated) character in it (idle animation) - works both in OS X and iOS
Start a run animation on the character. This works on OS X, run animation starts and loops. On iOS the character is positioned at the start of run animation. But it doesn't run...
If I start with e.g. run scene instead of idle, it works - character runs. The problem is when I start an animation (any) after the scene is loaded. It loads the model with the animation but doesn't play.
After detailed comparison between the OS X and iOS version I found 2 differences, which probably are related but I can't figure out how fix them:
In the OS X version the character is not animated until I start an animation. In the iOS version when I attach the nodes from the idle (or whatever other) scene to the root, it's animated. I don't know how to change this.
The OS X version has the scene.dae attached to the Scene View in the Storyboard - this is also the case in iOS. But in iOS for some reason this attachment is not working, ´self.scene´ is nil. This is why I have to instantiate and assign the scene programmatically. I couldn't fix it, tried re-adding the Scene View, assigning the outlet etc.
The scene kit view is added using storyboard. idle and run are .dae files. Each of them contains a full model with the character, and the animation. I just double checked that the animation identifiers are the same as in the .dae files. The models are actually provided in an example from Apple and work perfectly on OS X...
This is the code:
View controller:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidAppear:(BOOL)animated {
[self.sceneView loadScene];
}
#end
Scene kit view header:
// ASCView.h
#import <UIKit/UIKit.h>
#import <SceneKit/SceneKit.h>
#interface ASCView : SCNView
- (void)loadScene;
#end
Scene kit view implementation:
//
// ASCView.m
// anim_test
//
//
#import "ASCView.h"
#implementation ASCView
- (void)loadScene {
self.backgroundColor = [UIColor blueColor];
self.allowsCameraControl = YES;
[self loadSceneAndAnimations];
}
#pragma mark - Animation loading
- (void)loadSceneAndAnimations {
// Load the character from one of our dae documents, for instance "idle.dae"
NSURL *idleURL = [[NSBundle mainBundle] URLForResource:#"idle" withExtension:#"dae"];
SCNScene *idleScene = [SCNScene sceneWithURL:idleURL options:nil error:nil];
SCNScene *scene = [SCNScene sceneNamed:#"scene.dae"];
self.scene = scene;
NSLog(#"scene: %#", self.scene);
// Merge the loaded scene into our main scene in order to
// place the character in our own scene
for (SCNNode *child in idleScene.rootNode.childNodes)
[self.scene.rootNode addChildNode:child];
// Load and start run animation
// The animation identifier can be found in the Node Properties inspector of the Scene Kit editor integrated into Xcode
[self loadAndStartAnimation:#"run" withIdentifier:#"RunID"];
}
- (void)loadAndStartAnimation:(NSString *)sceneName withIdentifier:(NSString *)animationIdentifier {
NSURL *sceneURL = [[NSBundle mainBundle] URLForResource:sceneName withExtension:#"dae"];
SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithURL:sceneURL options:nil];
CAAnimation *animationObject = [sceneSource entryWithIdentifier:animationIdentifier withClass:[CAAnimation class]];
NSLog(#"duration: %f", [animationObject duration]); //0.9
animationObject.duration = 1.0;
animationObject.repeatCount = INFINITY;
[self.scene.rootNode addAnimation:animationObject forKey:#"foofoofoo"];
NSLog(#"animation: %#",[self.scene.rootNode animationForKey: #"foofoofoo"]);
NSLog(#"is paused: %#",[self.scene.rootNode isAnimationForKeyPaused: #"foofoofoo"] ? #"yes" : #"no"); //NO
}
#end
Ohh I found it. In iOS it seems I have to pass the options, in this case:
#{SCNSceneSourceAnimationImportPolicyKey:SCNSceneSourceAnimationImportPolicyPlayRepeatedly}
In OS X I don't - probably the defaults are different.
I am trying to make a custom Xcode UIPicker with only numbers 1-10. Is there any simple way to do this with an Identity Inspector or if not, what is the best way to go about making this simple UIPicker?
Thanks in advance!
No, you can't create a picker using only Inerface Builder. There is no equivalent to UITableView Static cells for UIPicker. You need a view controller but it's not that complicated. The view controller need to implement the UIPickerViewDataSource, UIPickerViewDelegate delegates. Here is the basics for a single column picker with the values 1 to 10.
#import "ViewController.h"
#interface ViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
#property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UIPickerView Data Source & Delegate
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 10;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [NSString stringWithFormat:#"%d", row + 1 ];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// TODO do something with the selection
}
#end
To create a minimal iOS app with a picker. Create a new Project select single window application. Replace the code in ViewController.m with above. Edit the story board and add a picker. Important You need to connect the picker view in the storyboard to the IBOutlet in the code.
Not Connected
To connect the outlet you should be editing the storyboard in assistant editor mode. The assisted editor will display the code and the IBOutlet property. Now "Control Click the picker view in the storyboard and drag to the line of code declaring the IBOutlet. The connection is made when the circle is black in the gutter on the line declaring the IBOutlet property.
Connected
Xcode Editing Storyboard in Assistant Editor Mode
FYI: By far the best and fastest moving way to learn iOS is the Stanford iTunes U Course:
Developing iOS 7 Apps for iPhone and iPad
https://itunes.apple.com/us/course/developing-ios-7-apps-for/id733644550
You will need to watch a few of the demos to grok how to make connections Interface Builder (IB). The first thing you need to understand is the IB does not create resource or configuration files. The storyboard files contain serialized interface objects. Almost identical to the objects you can create in code.
Changing the size of the picker text
You need to replace the implementation of pickerView:titleForRow:forComponent: with your own pickerView:rowHeightForComponent: and pickerView:viewForRow:forComponent:reusingView:
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return 60; // Row height in points, Note this should match the height of the UILabel Rect.
}
// FYI points are not pixels on non retina screens 1 point = 1 pixel but on retina screens 1 point = 2 pixels
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
if (view) {
UILabel *reuseLabel = (UILabel *)view;
reuseLabel.text = [NSString stringWithFormat:#"%ld", row + 1 ];
return reuseLabel;
}
UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
newLabel.text = [NSString stringWithFormat:#"%ld", row + 1 ];
newLabel.font = [UIFont systemFontOfSize:42];
newLabel.textAlignment = NSTextAlignmentCenter;
return newLabel;
}
I have tried many solutions but not worked yet! I'm developing iOS 6.1 iPhone app on Xcode 4.6.3.
I am using an MPMoviePlayerController in my application. I have 4 tabbed application. Movieplayer is in SecondViewController. I am not presenting it as a view controller but adding its view to my own view controller. The video plays just fine and I can go fullscreen.
Here's my code below. Any solutions?
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize moviePlayer;
- (IBAction)playVideo:(id)sender {
NSURL * url = [[NSURL alloc]initWithString:#"http://server:1935/live/test/playlist.m3u8"];
moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:url];
[self.view addSubview:moviePlayer.view];
moviePlayer.fullscreen = YES;
moviePlayer.allowsAirPlay = YES;
}
#end
I'm building a collection of forms each of which contains several fields. Some of the fields are UITextFields that will display a date. I've created a new class called DatePickerTextField, a descendant of UITextField. When a DatePickerTextField is tapped I'd like for a UIDatePicker control to appear in a popover.
My question is how do I use the storyboard to implement the popover? I can do a segue when there is a specific, visible control in the scene. But how do I represent a generic popover in the scene that I can attach to any instantiated DatePickerTextField that becomes active?
You can create segue that is not connected to any control but I don't think that there would be way to specify anchor point for popover from code. Another option is to create ViewController that is not connected with any segue. When editing storyboard, create ViewController which will be placed in popover, select it and navigate to Utilities pane->Attributes Inspector. Set Size to Freeform, Status Bar to None, specify unique Identifier that will be used to instantiate ViewController from code. Now you can change the size of ViewController by selecting its View and navigating to Utilities pane->Size Inspector.
After that you can create popover from code:
- (IBAction)buttonPressed:(id)sender {
UIView *anchor = sender;
UIViewController *viewControllerForPopover =
[self.storyboard instantiateViewControllerWithIdentifier:#"yourIdentifier"];
popover = [[UIPopoverController alloc]
initWithContentViewController:viewControllerForPopover];
[popover presentPopoverFromRect:anchor.frame
inView:anchor.superview
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
One caveat is that you need to hold reference to popover as ivar of your class, otherwise it'll crash because UIPopoverController would be released and deallocated after buttonPressed returns:
#interface MyViewController : UIViewController {
// ...
UIPopoverController *popover;
// ...
}
So, I had a similar issue, and in case others might benefit, I figured I'd share it, since I benefit so much from stackoverflow.
This solution allows you to set the anchor of a customizable popover segue. It also allows you to configure the segue to be modal or not (I could not find a way to prevent the segue by dimming the exterior context, so if someone knows how to do that, I would be interested in hearing it); this is accomplished by setting the passthrough views for the popover controller. I also added the capacity to specify a custom view, rather than the view of the source viewcontroller (since I needed this capacity); this portion is not critical to the solution.
DynamicPopoverSegue.h
#interface DynamicPopoverSegue : UIStoryboardPopoverSegue
#property BOOL isModal;
#property UIView* sourceView;
#property CGRect anchor;
#end
DynamicPopoverSegue.m
#implementation DynamicPopoverSegue
- (void)perform
{
if (!self.popoverController.popoverVisible)
{
UIViewController* dst = (UIViewController*)self.destinationViewController;
UIViewController* src = (UIViewController*)self.sourceViewController;
UIView* inView = _sourceView ? _sourceView : src.view;
self.popoverController.contentViewController = dst;
if (!_isModal)
{
[self.popoverController setPassthroughViews:[[NSArray alloc] initWithObjects:inView, nil]];
}
[self.popoverController presentPopoverFromRect:_anchor
inView:inView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
}
#end
Then you just set your segue to "Custom" in the storyboard, and set the segue class to "DynamicPopoverSegue". In my case, since I wanted to associate it with dynamic layers in a view, I could not set the anchor, so I created the segue by control clicking from the view controller icon in the bar beneath my view controller to the view controller I was using to present the popupover.
To call the popover segue:
[self performSegueWithIdentifier:#"MyPopoverSegue" sender:self];
And to configure the popover segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MyPopoverSegue"])
{
DynamicPopoverSegue* popoverSegue = (DynamicPopoverSegue*)segue;
// set the anchor to wherever you want it to be
popoverSegue.anchor = _destinationFrame;
}
}
- (IBAction)pressItemChooseOprateRoom:(id)sender {
if (isPad){
// UIView *anchor = sender;
UIViewController *viewControllerForPopover =
[self.storyboard instantiateViewControllerWithIdentifier:#"OperateRoomList"];
_myPopover = [[UIPopoverController alloc]
initWithContentViewController:viewControllerForPopover];
CGRect rc=[self getBarItemRc:sender];
[_myPopover presentPopoverFromRect:rc
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[MLControl shared].popover =self;
// [self perfformSegueWithIdentifier:SEGUE_POP_OPERATEROOM sender:self];
}else{
[self iphoneOpenOperateRoomList];
/* [self performSegueWithIdentifier:#"iPhonePushOperateRoom" sender:self];
*/
}
}
-(void)iphoneOpenOperateRoomList{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"OperateRoomList"];
// if (!index.showTabBar) {
// vc.hidesBottomBarWhenPushed = YES;
// }
[self.navigationController pushViewController:vc animated:YES];
}
Just used the answer from Jonnywho for my SWIFT project. In case you need it:
Here's the SWIFT version:
let anchor: UIView = sender
var viewControllerForPopover = self.storyboard?.instantiateViewControllerWithIdentifier("GameAboutViewController") as! UIViewController?
let popover = UIPopoverController(contentViewController: viewControllerForPopover!)
popover.presentPopoverFromRect(anchor.frame, inView: anchor, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
Add a UIView in the scene dock.
You can add it as a subview to any existing view on the view controller.
You can then toggle it's isHidden property as you require.
You can add multiple such subviews and create many such popups.
This technique will save you from setting up a new View Controller and using segues.
I have the problem depicted in the image when testing my app on a real device (iPhone 3G, 3.1.3).
It is fine in the simulator (xcode 3 with ios 4.1 sdk). sorry, can't post images yet, this is my first question here.
http://i.stack.imgur.com/Ct4on.jpg
I have the following code in the implementation of the annotation:
- (id)initWithLocation:(CLLocationCoordinate2D)coord {
self = [super init];
if (self) {
coordinate = coord;
}
return self;
}
And this is part of the header file:
#interface MyAnnotation : NSObject <MKAnnotation>
And this is where I create a new one (inside a loop):
MyAnnotation *theAnnotation = [[MyAnnotation alloc] initWithLocation:theCoordinate];
theAnnotation.title = [single objectForKey:#"address"];
theAnnotation.objID = [single objectForKey:#"id"];
[self.mapView addAnnotation:theAnnotation];
[theAnnotation release];
Any ideas about this? I don't know what to look :/
You could try to bring the (annotation)view to the front, when tapping on it.
So, when someone taps on an annotation, you should call [[self superview] bringSubviewToFront:self];
Best,
Christian