I am trying to implement an adWhirl view in the same view as one that has an MKMapView object. If I follow the standard steps that work fine with my tableViews, that is
awView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
[self.view addSubview:awView];
then the funny behavior starts. In the simulator it receives the touch and sends you on. But when running on my test device (running 3.1.3) the touch passes through to the map.
I have been told that this is because awView is being cast as a subView of mapView and that it must be its own view. But how? I have tried creating a separate UIView and then placing awView in it, then locating it at a fixed location, but instead of the fixed location, it loads relative to mapView and still does not receive touches.
Any suggestions?
Addendum: I thought that I was adding both as subviews but have not had any success. What I had done is to create two views in IB. The top one (firstView) has two subviews (bannerForAd and mapView.) This is what I have now
self.awView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
self.awView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[bannerForAd addSubview:awView];
mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
mapView = (MKMapView*)self.view;
mapView.delegate = self;
[firstView addSubview:mapView];
[firstView bringSubviewToFront:bannerForAd];
Now the map shows fine, but the ad is not even visible.
Stick both the AdWhirlView and the MKMapView as a subview of a UIView.
Related
I am trying to make a drawing application following this tutorial: http://www.effectiveui.com/blog/2011/12/02/how-to-build-a-simple-painting-app-for-ios/, and then I tried to make it such that I don't only draw on the entire screen, I only draw on a UIView that is inside of another UIView. (What I call a nested UIView)
My code is currently on github: https://github.com/sammy0025/SimplePaint
The only parts I tweaked with the original code from the tutorial is to change some class prefix names, enabled ARC so no deallocs, used storyboards (which works fine with the original code from the tutorial), and change this code in the main view controller implementation file (SPViewController.m):
-(void)viewDidLoad
{
[super viewDidLoad];
nestedView.backgroundColor=[UIColor colorWithWhite:0 alpha:0]; //This is to make the nested view transparent
SPView *paint = [[SPView alloc] initWithFrame:nestedView.bounds]; //original code is SPView *paint=[[SPView alloc] initWithFrame:self.view.bounds];
[nestedView addSubview:paint]; //original code is [self.view addSubview:paint];
}
My question is how do I make sure that I only draw inside the nested UIView?
Add clipping to your sub view. E.g. self.bounds would cover the whole area of a view.
UIBezierPath *p = [UIBezierPath bezierPathWithRect:self.bounds];
[p addClip];
I believe clipping for a view should be based on bounds initially and that you may shrink it by adding an new clipping. But there might be a difference between iOS and OS X here.
Rather than using an SPView inside a nested view, consider just changing the frame of the SPView to match what you want. This should solve your problem of only allowing drawing within a given rect.
I think you're seeing issues because of your storyboard configuration. I dont know much about storyboard, but I was able to get this to work programmatically by throwing out storyboard's view and building my own in viewDidAppear.
-(void)viewDidAppear:(BOOL)animated{
UIView *newView = [[UIView alloc] initWithFrame:self.view.bounds];
newView.backgroundColor = [UIColor greenColor];
SPView *newPaint = [[SPView alloc] initWithFrame:CGRectInset(self.view.bounds, 40,40)];
[newView addSubview:newPaint];
self.view = newView;
}
I have a subclassed UIView which I can get to scroll but not to zoom. I'm using autolayout so wondered if anything had changed in IOS6. In particular when are the scrollViewWillBeginZooming and scrollViewDidEndZooming methods implemented. My code looks like
- (void)viewDidLoad
{
[super viewDidLoad];
self.ringSet2 = [[RingView alloc] initWithFrame:CGRectMake(0, 0, 800, 800)];
[self.ringSet2 setDefaults];
/// ... more setup for other views but only ringSet2 is scrolled.
self.scrollview1.delegate=self;
self.scrollview1.scrollEnabled=YES;
self.scrollview1.contentSize=self.ringSet2.bounds.size
self.scrollview1.minimumZoomScale=0.2;
self.scrollview1.maximumZoomScale=5.0;
self.ringSet2.userInteractionEnabled=YES;
// ... needed elsewhere so other views can pick up their dimensionts
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
/// ... code for additional views
[self.scrollview1 zoomToRect:CGRectMake(0, 0, 200, 200) animated:YES];
[self.scrollview1 addSubview:self.ringSet2];
}
with
-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return self.ringSet2;
}
and scrollViewWillBeginZooming etc. implemented just to trace what is happening. Interesting,
viewForZoomingInScrollView appears to get called only once, as is scrollViewDidEndZooming with a scale value just under one but scrollViewWillBeginZooming is never called. The property ringSet2 is defined
#property (strong, nonatomic) IBOutlet RingView *ringSet2;
as the view does not appear if it's defined as weak.
Apologises for this. The answer is really stupid. I'm currently developing under IOS 6.0 on the simulator whilst my phone is still on IOS 5. The simulator allows you to simulate pinches but only centred on the centre of the screen. The scrollview however only receives this signal if it too is in the centre which was not the case in my initial build. Moving the scroll view's rectangle into the centre fixed the problem. You would not make this mistake testing on a real device. The code is thus OK. Lost 3 or 4 evenings pulling my hair over this one.
Before iOS6 I used to rotate the MKMapView based on the user's GPS-direction (NOT HEADING), using a subview of the MKMapView. It all worked perfectly, I initialized the view as follows:
mapView = [[MKMapView alloc] init];
mapView.delegate = self;
mapView.clipsToBounds = FALSE;
mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.view = mapView;
And when rotating I did the following:
UIView *innerMap = [mapView.subviews objectAtIndex:0];
if([innerMap isKindOfClass:[UIView class]])
{
innerMap.transform = CGAffineTransformMakeRotation(degreesToRadians(-lastDegrees));
}
As I said, all worked perfectly. The nice thing was then when the map rotated, it automatically scaled to the entire frame of the view and filled the black corners that the rotation created.
However, the new iOS6 Maps does not scale and fill the corners! So when it rotates, half of the view is missing and the other half is black (background-color).
What have I tried?
Trying all different subviews of the new MKMapview (also set their resizingmask to the same value as the mapview)
Tried to set the contentmode to scaleToFill (also in the subviews)
Tried to set the autoresizes subviews to true
Tried to reset the frame after rotating
Unfortunately, all my attempts have no effect at all. Somehow the GoogleMaps scaled and filled the black corners automatically and the iOS Maps do not. So am I missing something here, some awesome property of UIView that I'm forgetting or is this simply not possible with the new iOS6 Maps?
What about making the MapView much larger than the screen size so when it rotates you can't seen around it?
I am trying to get some AdWhirl ads to work with my app, but I am having a bit of trouble positioning them. The ads work just fine with the following code in my viewDidLoad method:
AdWhirlView *adWhirlView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
[self.view addSubview:adWhirlView];
The problem is that it displays the add across the top of the view. I am assuming this is because the default drawing area is from 0,0. I don't know how to change the self.view line to draw it towards the bottom of the screen.
Try it like this....
AdWhirlView *adWhirlView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
adWhirlView.frame = CGRectMake(0.0f, 100.0f, adWhirlView.frame.size.width, adWhirlView.frame.size.height);
[self.view addSubview:adWhirlView];
It should show the new view further below (100 points) - adapt that 100.0f according to your needs.
view.frame = CGMakeRect(x,y,w,h);
Is it possible to create a view with both an MKMapview and another subview. In particular I have a map view and I have been trying to add a second subview (to the superview, not the MKMapView.) The problem is that while both view can be seen any touches to the UIView that is not the MKMapView pass through to the map. I even tried to move the map so that they do not overlap but the other UIView locates itself relative to the map, not the window.
An additional curiosity is that the code works fine on the simulator, but not on a test device that is running 3.1.3. Could this be a problem with the 3.1.3 version of MKMapView or just a quirk in the simulator?
My code is
combinedView = [[UIView alloc] initWithFrame:self.view.frame];
self.awView = [[AdWhirlView alloc] init];
awView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
self.awView.delegate = self;
[combinedView addSubview:awView];
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0,50,320,430)];
mapView = (MKMapView*)self.view;
mapView.delegate = self;
//[self.view insertSubview:mapView atIndex:0];
[combinedView addSubview:mapView];
//mapView.showsUserLocation = YES;
// Create a location coordinate object
CLLocationCoordinate2D coordinate;
coordinate.latitude = 40.1;
coordinate.longitude = -76.30575;
// Display map
mapView.region = MKCoordinateRegionMakeWithDistance(coordinate, 40000, 40000);
[combinedView bringSubviewToFront:awView];
Thanks for any advice.
Not too familiar with AdWhirlView, but is it possible you need to set a frame for that as well? CGRectMake(0,0,320,50); or something?
Otherwise, you might want to play with the autoresizeMasks of the two views. I know for certain you can have a MKMapView with sibling views, and they all work fine.