UIImageView not responding to centering - ios

I'm trying to put together a simple compass for iOS. The rotation animation seems to rotate the compass image around the center of the screen so I am trying to automatically center the UIImageView of compass Image so that it will work on different devices.
And this is where my problem is. I have attempted to center the image with the following code within ViewDidLoad but with no result:
compassImage.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));
I have originally placed the compass image in a random place within the Storyboard just to make sure this works. I have printed NSLog checks before and after this centering code to make sure that it is having and effect and it does seem to be centering the image (on my iPhone 4s) yet this is not reflected in the view:
2014-05-17 12:18:23.015 Compass[447:60b] Old: 160, 386
2014-05-17 12:18:23.019 Compass[447:60b] New: 160, 240
I'd post an image but am not allowed as it is my first post.
In fact heres the whole setup. I'm sure I've gone wrong somewhere:
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) IBOutlet UIImageView *compassImage;
#property (nonatomic, retain) IBOutlet UILabel *trueHeadingLabel;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController()
#end
#implementation ViewController
#synthesize locationManager, compassImage, trueHeadingLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Old: %i, %i", (int)compassImage.center.x, (int)compassImage.center.y);
compassImage.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));
NSLog(#"New: %i, %i", (int)compassImage.center.x, (int)compassImage.center.y);
locationManager=[[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.headingFilter = 1;
locationManager.delegate=self;
// Start the compass updates
[locationManager startUpdatingHeading];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// Convert Degree to Radian
// Multiply by -1 to twist opposite to phone rotation
float oldRad = -manager.heading.trueHeading * M_PI / 180.0f;
float newRad = -newHeading.trueHeading * M_PI / 180.0f;
// creating needle spin animation
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:#"transform.rotation"];
theAnimation.fromValue = [NSNumber numberWithFloat:oldRad];
theAnimation.toValue=[NSNumber numberWithFloat:newRad];
theAnimation.duration = 0.5f;
// applying the animation
[compassImage.layer addAnimation:theAnimation forKey:#"animateMyRotation"];
compassImage.transform = CGAffineTransformMakeRotation(newRad);
// setting labels to heading
trueHeadingLabel.text = [NSString stringWithFormat:#"%i°", (int)(newHeading.trueHeading)];
// console print of heading
NSLog(#"True heading: %f", newHeading.trueHeading);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I have looked at pretty much every question and answer on here with anything to do with changing the position of a UIImageView and centering and nothing is doing the job. I get the feeling that it could just be the way I'm setting up the whole program and this wouldn't be a surprise since I am a new and super-inexperienced. Any help would be fantastic. Even advice on better programming practice too. If you need any more information gimmie a shout.

Sounds like you may have autolayout enabled and that overrides your code.

Change:
compassImage.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));
To:
compassImage.center = self.view.center;
Also, make sure that you have no constraints on the compassImage in IB that would interfere.

Related

mapview autozoom on current location automatic

I have one problem. I've been looking at the other answers here on stack overflow about the same question and I can't get them to work for me. So I'm going to try asking here. What I want to do is when I'm on map view and have got the user location I want to automatically zoom into the location.
the h-file
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface WalkingTableViewController: UIViewController <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *MKMapView;
#end
the m-file
#import "WalkingTableViewController.h"
#interface UITableViewController ()
#end
#implementation WalkingTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.MKMapView.showsUserLocation=YES;
self.MKMapView.delegate = self;
[self.MKMapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
- (IBAction)StopButton:(id)sender
- (IBAction)StartButton:(id)sender
#end
If you like to see the zoom animated, I would place the code in the viewDidAppear method, so that the animation starts once the view controller is displayed.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CLLocationManager* tempLocationManager = [[CLLocationManager alloc] init];
MKCoordinateRegion tRegion = MKCoordinateRegionMakeWithDistance([tempLocationManager.location coordinate], 20000, 20000);
[self.MKMapView setRegion:tRegion animated:animated];
}
Adjust the region (zoom level, 20000 in the example above) to your needs.
What you have to do is tell the mapview to zoom into a region. This should get you started:
CLLocationCoordinate2D center = _mapView.userLocation.coordinate;
MKCoordinateRegion region = MKCoordinateRegionMake(center, MKCoordinateSpanMake(2000, 2000));
[_mapView setRegion:region animated:YES];

How to call a variable from another class

First off, do you guys know of any good tutorial sites or books to learn how to code for iOS6?
Now to the problem at hand, I have an AppDelegate class and a ViewController class.
I am using the AppDelegate class to find my current location and save it as an NSString.
I have a label in my ViewController class where I want to display my location.
In java I would usually just do something like this
label.text = AppDelegate.myLocationString;
But I am fairly new to objective c and I don't know how to do the equivalent. To be honest I'm not even sure if I am taking the correct approach for this language. Is there another way to approach this problem in objective c?
I've tried searching around for how to do it but I'm not even sure that I'm phrasing my searches correctly so I don't know if I'm searching in the right direction.
Any help that could be offered would be very much appreciated
My code as it is now:
AppDelegate.h
#import <UIKit/UIKit.h>
#import CoreLocation/CoreLocation.h
#class BIDViewController;
#interface BIDAppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) BIDViewController *viewController;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) NSString *myPosition;
#end
LocationManager class from AppDelegate.m
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDate *eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15) {
//if it is within the last 15 seconds, use it. Else do nothing.
if (newLocation.horizontalAccuracy < 35.0) {
//location seems pretty accurate so we will use it
NSLog(#"latitude: %+.6f, longitude: %+.6f\n", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
NSLog(#"Horizontal accuracy: %f", newLocation.horizontalAccuracy);
int latDegrees = newLocation.coordinate.latitude;
int lonDegrees = newLocation.coordinate.longitude;
double latDecimal = fabs(newLocation.coordinate.latitude - latDegrees);
double lonDecimal = fabs(newLocation.coordinate.longitude - lonDegrees);
int latMinutes = latDecimal * 60;
int lonMinutes = lonDecimal * 60;
double latSeconds = ((latDecimal * 3600) - (latMinutes * 60));
double lonSeconds = ((lonDecimal * 3600) - (lonMinutes * 60));
_myPosition = [NSString stringWithFormat:#"Lat: %d, %d, %1.4f, Lon: %d, %d, %1.4f", latDegrees, latMinutes, latSeconds, lonDegrees, lonMinutes, lonSeconds];
}
}
}
ViewController.h
#import <UIKit/UIKit.h>
#interface BIDViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *positionLabel;
#end
ViewController.m
#import "BIDViewController.h"
#import "BIDAppDelegate.h"
#interface BIDViewController ()
#end
#implementation BIDViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//I have tried setting the label's text here but to no avail so far, I have been
//able to set it as "blah" with the following line:
//
// positionLabel.text = #"blah";
//
//and I have tried things such as the following to populate the label with the
//myPosition variable:
//
// positionLabel.text = _myPosition;
// or
// positionLabel.text = AppDelegate._myPosition;
}
- (void)viewDidUnload
{
[self setPositionLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
To reference the App Delegate from your view controller, first import its definition (which you've ready done):
#import "BIDAppDelegate.h"
and then in code get the delegate:
BIDAppDelegate *appDelegate = (BIDAppDelegate *)[[UIApplication sharedApplication] delegate];
and then get the location from the delegate:
CLLocation *location = appDelegate.locationManager.location;
and then call whatever method you like on the location object:
NSString *descr = location.description;
Or get the pre-calculated position with:
NSString *position = appDelegate.myPosition;
In your ViewController
BIDAppDelegate *appDelegate = (BIDAppDelegate *)[UIApplication sharedApplication].delegate;
[positionLabel setText:appDelegate.myPosition];
How to call a variable from another class?
Assume you are in ClassB
ClassA *aObj=... ; //create an object of ClassA
aObj.propertyName=...;//set the property or ivar
NSString *string=aObj.propertyName;//retrieve it
do you guys know of any good tutorial sites or books to learn how to
code for iOS6?
http://www.lynda.com/Apple-training-tutorials/106-0.html
http://www.raywenderlich.com/tutorials

Set slider value

i try to set a value to a slider after a button click,
but it does not work - the slider does not move. the code runs fine without mistakes.
It should be pretty simple but I can't figure it out.
xCode Version 4.5.2
Thanks!
here my code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *debugLabel;
#property (weak, nonatomic) IBOutlet UISlider *slider;
- (IBAction)slider:(id)sender;
- (IBAction)ButtonChangeValue:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize slider;
...
- (IBAction)slider:(UISlider *)sender {
float value = [sender value];
self.debugLabel.text = [NSString stringWithFormat:#"Value: %f",value];
}
- (IBAction)ButtonChangeValue:(id)sender {
slider.value = 90;
}
I think your problem is that the slider accepts values between 0.0 and 1.0 (default values, change them with _slider.maximumValue and _slider.minimumValue). Try setting the value to 0.9 instead of setting 90 (if you mean 90%).
If the slider updates but is not animated, use :
[_slider setValue:0.9 animated:YES];
Note that given your code, you may need to use self.slider instead of _slider.
try using
self.slider.value = 90;
instead of
slider.value = 90;
Check My Answer
- (void)viewDidLoad
{
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sliderTapped:)];
[slider addGestureRecognizer:gr];
}
- (void)sliderTapped:(UIGestureRecognizer *)g
{
UISlider* s = (UISlider*)g.view;
if (s.highlighted)
return; // tap on thumb, let slider deal with it
CGPoint pt = [g locationInView: s];
CGFloat percentage = pt.x / s.bounds.size.width;
CGFloat delta = percentage * (s.maximumValue - s.minimumValue);
CGFloat value = s.minimumValue + delta;
[s setValue:value animated:YES];
NSString *str=[NSString stringWithFormat:#"%.f",[self.slider value]];
self.lbl.text=str;
}
To use slider.value = 90;
Your ViewController.h should be:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
UISlider *slider;
}
#property (weak, nonatomic) IBOutlet UILabel *debugLabel;
#property (weak, nonatomic) IBOutlet UISlider *slider;
- (IBAction)slider:(id)sender;
- (IBAction)ButtonChangeValue:(id)sender;
#end
And don't forget #synthesize slider; in your ViewController.m as well.
Otherwise, use self.slider.value = 90; or _slider.value = 90;
For Swift, you can use:
slider.setValue(5.0, animated: true)
Since you are using interface builder first thing to look at would be: are the UI components (slider, button) connected to the IBOutlets in File's owner. This is the most common source of problems like this.
Then check the min and max of the slider (default is 0;1 - as rdurand mentioned).
And spider1983 is correct also: since slider is a property, you can address it as self.slider (or _slider, but you shouldn't use the last one in this case).
i think . as you have not mentioned maximum and minimum value of slider ,it is taking default max and min values that are 0 to 1. So it is not possible to set value =90. First change its max and min like this :
Slider.minimumValue = 1;
Slider.maximumValue = 100;
now try your thing ,
Slider.value =90;
Within view
#State private var value1: Double = 0.9
Then make reference
Slider(value: $value1)

UISlider moving UIImage

I am using a UIslider to move a UIImage left and right on the screen. When the UISlider is totally on the left the image will be to a certain position on the X atis on the left of the screen, and when the slider is totally to the right, the image is on the right of the screen. If for example I want to give the image flexibility movement of 600px, how can I do that?
-(IBAction)sliderValueChanged:(UISlider *)sender
{
if (sender.value >= 0.5) {
int value;
value = sender.value * 6;
[photoView setFrame:CGRectMake(photoView.frame.origin.x + value,
PhotoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}else{
int value;
value = sender.value * -6;
[photoView setFrame:CGRectMake(photoView.frame.origin.x + value,
photoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}
...this was my guess
I recently had to do the same thing you're trying to do for use in a full scale aircraft where the iPad/iPhone acts as a instrument gauge.
Here is the code I used to move an image for the aircraft's instrument readout: Also, you should round the float value to an int because we are dealing with whole pixel points. (The image will still move fine with a float value, but I like using an int when dealing with pixel points.)
#import "ViewController.h"
#import <math.h>
#interface ViewController()
#property (nonatomic, strong) IBOutlet UIImageView *XAxis;
#property (nonatomic, strong) IBOutlet UISlider *XSlider;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.XSlider.minimumValue = 0.0f;
self.XSlider.maximumValue = 600.0f;
}
- (IBAction)XValueChanged:(UISlider *)XSlider;
{
int XResult = (int)floorf(XSlider.value);
self.XAxis.center = CGPointMake(self.XAxis.center.x, XResult);
NSLog(#"X Value: %d", XResult);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
How about something like this,
slider.minimumValue = 0.0f;
slider.maximumValue = 600.0f;
-(IBAction)sliderValueChanged:(UISlider *)sender
{
[photoView setFrame:CGRectMake(sender.value, PhotoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}
You can also do this by changing photoView.frame.origin.x + value to floatValue + value where floatValue is some fixed number based on where you want to set the photoView. Also calculate value as value = sender.value * constant where constant again depends on how much you need to move it for each slider movement.
Check documentation for more details on properties

MKMapView not updating with calls to setRegion:animated

I'm trying to learn how to use MKMapView and have created a sample application to do so; however, in my code I'm making a call to setRegion:animated to change the center point and the span, but the map never updates. I've run through a few threads on StackOverflow (SO) where others have mentioned similar problems and tried implementing their solutions to no avail.
Things I made sure to try in my code based on other's SO threads I found:
Ensure I initialized the MKMapView with a frame
Tried running the setRegion:animated method call on the main thread
My included my code below, can anyone shed some light on why my MKMapView instance will not update it's view?
EDIT: Correct code shown below:
MK_ViewController.h:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MV_ViewController : UIViewController {
IBOutlet MKMapView *myMapView;
MKCoordinateRegion defaultRegion;
CLLocationCoordinate2D defaultCenter;
MKCoordinateSpan defaultSpan;
}
#end
MK_ViewController.m:
#import "MV_ViewController.h"
#interface MV_ViewController ()
#end
#implementation MV_ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// initialize default map view properties
defaultCenter = CLLocationCoordinate2DMake(33.732894,-118.091718);
defaultSpan = MKCoordinateSpanMake(0.028270, 0.0465364);
// Setup MapView's inital region
defaultRegion = MKCoordinateRegionMake(defaultCenter, defaultSpan);
// create the map view
CGRect screenRect = [[UIScreen mainScreen] bounds];
myMapView = [[MKMapView alloc] initWithFrame:screenRect];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// update map's initial view
[myMapView setRegion:defaultRegion animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
MK_ViewController+MKMapViewDelegate.m:
#import "MV_ViewController.h"
#implementation MV_ViewController (MKMapViewDelegate)
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
MKCoordinateRegion region = mapView.region;
CLLocationCoordinate2D center = region.center;
MKCoordinateSpan span = region.span;
NSLog(#"Center (lat,lon): (%f,%f)",center.latitude,center.longitude);
NSLog(#"Span (lat,lon): (%f,%f)",span.latitudeDelta,span.longitudeDelta);
}
#end
I solved the issue by removing the MKViewMap object from the NIB, and instead added it using the following code in the MK_ViewController.m file:
[self.view addSubView:myMapView];
The issue was that the NIB wasn't properly wired up to the view controller, and the view controller was creating it's own map view.
Thank you #Jason Cabot for pointing me in the right direction.

Resources