Positioning sprites inside scene - position

I would like when i create all my sprites to get centred in the screen, but that is not the case, i have a sprite when i set it's position to CGPointMake(self.size.width / 2, self.size.height / 2) it gets centred vertically but not horizontally, when i set it to CGPointMake(0, 0) it sets at the bottom of the screen with only half of it's body visible ( which is what you expect) but horizontally it doesn't get positioned right ( half his vertical body appears ) until i set it's X to 300.
How come the sprite's Y position gets set right but the X doesn't ?
scene.scaleMode = .AspectFill
and i haven't set any anchorPoint, 4' screen.
UPDATE:
I'm using Portrait, played around with different scaleMode and found out that the perfect (0, 0) that sets the sprite on the bottom left is:
scene.scaleMode = .ResizeFill
It also works fine with different screen sizes,but (self.size.width / 2) puts it further to the left.Do you think it's the best setting for all SpriteKit Portrait projects?

I tried to reproduce what you are saying, but I couldn't, either using .sks file or not for loading the scene. Also I've produced good results on both 7.1 and 8.1 simulators...The thing is that simulators sometimes could be tricky and not 100% reliable, so you should not trust them much.
I don't know if this will help you, but you should consider it...In Xcode 5 projects scene is programmatically created to have a size of the view. Basically it's done in viewDidLoad method like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
Or using viewWillLayoutSubviews like LearnCocos2D pointed:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
skView.showsDrawCount = YES;
//skView.showsQuadCount = YES;
skView.showsPhysics = YES;
skView.ignoresSiblingOrder = YES;
if(!skView.scene){
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
}
But Xcode 6 uses an SKS file:
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
}
}
If you look at the GameScene.sks you can see that the default scene size is 1024x768.
Try to print your scene size as well as view's bounds size to see actuall sizes. You can use something like:
println("view.bounds\(view.bounds), self.size\(self.size)")
I don't know if any of this helped, but I hope it will lead you somewhere. Goodluck!

Related

How to overlay MKPolyline on top of different maps

So I draw a MKPolyline with the users updated CLLocationCoordinates as per usual. When my quits and starts again, all of the past points are loaded onto the mapview to be displayed with
routeLine = [MKPolyline polylineWithCoordinates:clCoordinates count:numberOfSteps];
[_mapView addOverlay:routeLine];
and in MKOverlayRenderer method I have
if ([overlay isKindOfClass:[MKPolyline class]])
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
renderer.strokeColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
renderer.lineWidth = 3;
return renderer;
}
This all works a treat, but problems arise when I change the type of map with
[self resetMapViewAndRasterOverlayDefaults];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
_rasterOverlay = [[MBXRasterTileOverlay alloc] initWithMapID:#"jonobolitho.j834jdml"];
_rasterOverlay.delegate = self;
[_mapView addOverlay:_rasterOverlay];
Note, I have the resetMapViewAndRasterOverlayDefaults helper method
// Reset the MKMapView to some reasonable defaults.
//
_mapView.mapType = MKMapTypeStandard;
_mapView.zoomEnabled = YES;
[_mapView removeAnnotations:_rasterOverlay.markers];
[_mapView removeOverlay:_rasterOverlay];
[_rasterOverlay invalidateAndCancel];
I am using MBXMapKit to display the maps. The maps display correctly, but the polyline isn't shown on top of the map. The map just loads over the top of my polyline (routeLine). I know this because in between the tiles of the new map I can see the routeLine underneath.
So basically is there a way to load the MKPolyline but always keep it on the top layer of the map, even if it changes?
Instead of:
[_mapView addOverlay:_rasterOverlay];
You want:
[_mapView insertOverlay:_rasterOverlay belowOverlay:routeLine];
Or something similar. Overlays have an order.

Centre location not updating, puts me in the middle of the ocean?

Stuck on something very basic, just started up with MKMapView and trying to get it to zoom in on my location.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate; }
This code seems to just not be working, I understand it usually takes a little bit of time to get the location and i have left it for a while with now luck. However the location shows up correctly but it doesn't centre in on this (it centres into the very middle of the map just off west africa)
I also have the following code in viewDidLoad, which seems to be correct as it zooms in to the specified height, just not place.
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 20000, 20000);
[self.mapView setRegion:region animated:YES];
EDIT: It seems to be working on the simulator now after pressing back once or twice and then re-viewing to the map. But it doesn't work on my iPhone still. I have checked all the location services settings and they seem to be all on.
I use the following code to set center and span to be shown in MapView. It should work.
MKCoordinateRegion region = {{0,0},{.5,.5}};
region.center.latitude = doubleLattitude;
region.center.longitude = doubleLongitude;
[mapView setRegion:region animated:YES];
If a MKMapView centers to just west of Gabon, it's very likely that one of your objects is nil and thus the coordinate is 0° latitude and 0° longitude. You can easily test it by setting a breakpoint in the debugger and analyzing your objects.
self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
Does not center map on user location.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation is called only first time when device gets user location,
better use - (void)locationManager:didUpdateToLocation: fromLocation:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
if(newLocation.horizontalAccuracy>0)
{
// set center of map (span will not be changed in this case)
[mymap setCenterCoordinate:newLocation.coordinate animated:YES];
// or use region to specify both span and center
MKCoordinateRegion region.span.latitudeDelta = .05 ;
region.span.longitudeDelta = .05 ;
region.center.latitude = newLocation.coordinate.latitude ;
region.center.longitude = newLocation.coordinate.longitude ;
[mymap setRegion:region animated:TRUE];
}
}

MonoTouch: How to resize a view.Frame inside Draw override and draw correctly?

the problem I am having it that if inside the UIView Draw override, I change the view frame size, drawing a rectangle is not working as expected.
If I change the view frame size outside of the Draw override, it works fine. Is this an expected behavior or is it a problem with monotouch only?
This is the code I am using:
class ChildView : UIView
{
public override void Draw (RectangleF rect)
{
base.Draw (rect);
CGContext g = UIGraphics.GetCurrentContext();
//adding 30 points to view height
RectangleF rec = new RectangleF(this.Frame.Location,this.Frame.Size);
rec.Height+=30;
RectangleF rec_bounds = new RectangleF(0,0,rec.Width,rec.Height);
this.Frame=rec;
this.Bounds=rec_bounds;
//drawing a red rectangle to the first half of view height
UIColor.Red.SetFill();
RectangleF _rect = new RectangleF(this.Bounds.Location,this.Bounds.Size);
_rect.Height=_rect.Height/2;
g.FillRect(_rect);
}
}
However, the output of this code is this: (it should draw only 30 points red, but it draws 60 points)
Here is a link to download the project to reproduce this issue:
www.grbytes.com\downloads\RectangleDrawProblem.rar
Καλημέρα!
This behavior is expected. If you want to change the view's frame inside the Draw override, do it before getting the current context. That is because the graphics context also has a size and that is the size of the view at the time you are retrieving it.
Also, there is no need to set both the Bounds and the Frame of the view. You can just set either of them in this case.
By the way, I don't think you need to call base.Draw(). According to the Apple documentation, "If you subclass UIView directly, your implementation of this method does not need to call super."

how can I set contentoffset and change the height of UIScrollview at same time

I'm trying to scroll up my UISCrollView when the keyboard is shown
I use setContentOffset to shift the uiview up.
At the same time I want to decrease the height of my UISCrollView to (view height - keyboard height), so that the entire content view can be scrolled.
I apply both the changes in keyboardWillShow notification
When I actually bring the keyboard up in my app, the contents first get pushed up and then they are pushed down (which gives a flickering effect). I'm trying to smooth out both the transformations in one go..
Is it possible?
Code Below ---
- (void) keyboardWillShow {
CGPoint contentOffset = scrollView.contentOffset;
CGRect scrollViewFrame = scrollView.frame;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
if (contentOffset.y >= 0 && contentOffset.x >= 0) {
isContentOffset = YES;
contentOffset.y += screenShift;
[scrollView setContentOffset:contentOffset animated: NO];
}
scrollViewFrame.size.height = keyboardOrigin.y - self.view.frame.origin.y - toolbarHeight;
scrollView.frame = scrollViewFrame;
[UIView commitAnimations];
}
There is an option for animation when you setContentOffset for animation. here is the code that i use all the time
- (void)textViewDidBeginEditing:(UITextView *)textView
{
svos = scrollView.contentOffset;
CGRect rect = [textView bounds];
rect = [textView convertRect:rect toView:self.scrollView];
CGPoint point = rect.origin ;
point.x = 0 ;
[self.scrollView setContentOffset:point animated:YES];
doneButton.enabled = YES;
}
- (IBAction)donePressed
{
[scrollView setContentOffset:svos animated:YES];
[textview resignFirstResponder];
doneButton.enabled = NO;
}
It works fine for me.
Are you wrapping these changes in an animation block?
[UIView beginAnimations:#"resizeScroll" context:nil];
// make your changes to set and content offset
[UIView commitAnimations];
I think I have got a solution for this. You can handle the resize of the view in textViewDidBeginEditing method. You can just change the frame size of the scrollView to half by
CGRect tframe = myscrollView.frame;
tframe.size.height/=2;
myscrollView.frame = tframe;
and to initialize or handle the total length of the scrollview you can set the contentSize of the scrollView in the similar fashion as the frame was set in above snippet. for example
CGSize tsize = self.view.frame.size;
//here you can change the height and width of the scrollView
myscrollView.contentSize = tsize;
I hope this should do the trick for you. If it does please communicate.
Figured out the issue...
When the keyboard button was clicked, I was doing a becomeFirstResponder followed by a resignFirstResponder on keyboard view. This caused keyboardWillShow followed by keyboardWillHide and another keyboardWillShow notification, which brought the keyboard up, brought it back down and then up again.
Thanks to everybody who tried to help out.. and sorry the issue was pretty different...

Monotouch - make UIView scrollable

I have a view with 4 text boxes and and a logo at the top - when the user is entering information the text pad covers up some of these controls, how can I make the view scroll so that this isn't an issue.
I have tried adding the view to a UIScrollView but that doesn't seem to do anything?
I've included a snippit below of how I've handled your situation. If I'm understanding you correctly, you do not wish to have a scrollable view, rather you want to the view to move in conjunction with switching to and from fields to alleviate and visual hindrances caused by the keyboard.
Goodluck!
private void ScrollTheView(bool movedUp, float scrollamount, UIView ViewToMove)
{
//To invoke a views built-in animation behaviour,
//you create an animation block and
//set the duration of the move...
//Set the display scroll animation and duration...
UIView.BeginAnimations(string.Empty, System.IntPtr.Zero);
UIView.SetAnimationDuration(0.15);
//Get Display size...
RectangleF frame = ViewToMove.Frame;
if (movedUp) {
//If the view should be moved up,
//subtract the keyboard height from the display...
frame.Y -= scrollamount;
}
else {
//If the view shouldn't be moved up, restore it
//by adding the keyboard height back to the original...
frame.Y += scrollamount;
}
//Assign the new frame to the view...
ViewToMove.Frame = frame;
//Tell the view that your all done with setting
//the animation parameters, and it should
//start the animation...
UIView.CommitAnimations();
}
You need to set more to the UIScrollView than just put subviews in it. Set up the ContentSize property properly for the complete size of the subviews so the scrollview knows about the larger content in it, than you can control the scrolling position, zoom factor and so on.
There are plenty of samples on iOS SDK, just check the UIScrollView documentation, transformation to Monotouch from ObjectiveC is straightforward or check blog post at http://blog.touch4apps.com/home/iphone-monotouch-development/monotouch-infinite-loop-image-scroll-view where I have a sample with images autoscrolled in UIScrollView.
something like this.
textBox.EditingDidBegin += delegate {
var offset = scrollView.contentOffset;
offset.Y -= 200;
scrollView.contentOffset = offset;
}

Resources