iOS 7 Views reposition under status bar using topLayoutGuide - layout

I have seen many confusing and heck solutions to deal with status bar in iOS 7 but I liked following solution as mentioned by Apple at - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926
....but it doesn't work! This method gets called as expected but childView is not moving down 20 pixels.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
UIView *childView = self.childController.view;
id topGuide = self.topLayoutGuide;
CGFloat topBarOffset = self.topLayoutGuide.length; //I checked this valued is 20
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings (childView, topGuide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: #"V:[topGuide]-20-[childView]"
options: 0
metrics: nil
views: viewsDictionary
]
];
}
}
Following works for me but I would really like to solve this problem using AutoLayout using topLayoutGuide.
- (void)layoutSubviews
{
[super layoutSubviews];
self.backgroundColor = [UIColor blackColor];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
CGRect frame = self.bounds;
frame.origin.y = 20;
frame.size.height -= 20;
self.childView.frame = frame;
} else {
self.childView.frame = self.bounds;
}
}
Any ideas why using topLayoutGuide not working? Thanks.

Related

"Adjust to fit" causes memory leak for UITextField category (or subclass)

When using a category on UITextField, the "Adjust to fit" and minimum font size options may cause a memory leak, when text inside such a field exceeds its visible boundaries. I tried subclassing instead, but it did not solve the problem.
Here is how my category implementation looks like:
#implementation UITextField (custom)
static NSString *fontName = #"My-Awsome-Font";
static UIColor *color;
static UIFont *smallFont;
static UIFont *largeFont;
static NSDictionary *smallAttributes;
static NSDictionary *largeAttributes;
static NSString *placeholder;
static bool shouldModifyPlaceholder;
- (CGRect)textRectForBounds:(CGRect)bounds
{
if(largeFont == nil)
largeFont = [UIFont fontWithName:fontName size:20.0];
if(smallFont == nil)
smallFont = [UIFont fontWithName:fontName size:16.0];
if(smallAttributes == nil)
smallAttributes = #{NSFontAttributeName: smallFont};
if(largeAttributes == nil)
largeAttributes = #{NSFontAttributeName: largeFont};
// general elements
[self setBackgroundColor:[UIColor whiteColor]];
[self.layer setBorderColor:[UIColor whiteColor].CGColor];
[self.layer setBorderWidth:2.0];
self.font = largeFont;
self.layer.cornerRadius = 3;
self.clipsToBounds = YES;
//
shouldModifyPlaceholder = [self respondsToSelector:#selector(setAttributedPlaceholder:)] && ![placeholder isEqualToString:self.placeholder];
// custom elements for each size category
if (self.frame.size.width <= 90) {
if (shouldModifyPlaceholder) {
if ([self.placeholder length] > 3) {
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:smallAttributes];
}
else {
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:largeAttributes];
}
placeholder = self.placeholder;
}
return CGRectMake(bounds.origin.x + 18, bounds.origin.y + 9,
bounds.size.width - 36, bounds.size.height - 16);
}
else {
if (shouldModifyPlaceholder) {
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:largeAttributes];
placeholder = self.placeholder;
}
return CGRectMake(bounds.origin.x + 20, bounds.origin.y + 9,
bounds.size.width - 40, bounds.size.height - 16);
}
}
Recently I discovered that typing "too much" text into a UITextField caused my app to use up all the phone's memory and crash. I found out that it was due to the fact that my customisation did not work well with the "Adjust to fit" option. Removing "Adjust to fit" fixed the issue. I also set minimum font size property to the original font size to be sure. And since I used well over a day trying to find a solution, I thought I'd share this in case someone else runs into this problem.

Custom layout on iOS 7 renders element to high

I have a problem with custom layout on iOS 7. Everything appears too high, i.e. under the navigation bar. On iOS 6 it works like a charm even when compiled with iOS 7 SDK.
Below I post code used to init and layout the view. I don't use Interface Builder and I would prefer not to. Any help appreciated.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.documentTitle = [UITextField new];
self.documentExtension = [UILabel new];
self.documentTitle.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Document title"];
self.documentTitle.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize] + 1];
self.documentTitle.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
self.documentTitle.borderStyle = UITextBorderStyleRoundedRect;
self.documentTitle.returnKeyType = UIReturnKeyDone;
self.documentTitle.keyboardType = UIKeyboardTypeDefault;
self.documentExtension.text = #".pdf";
self.documentExtension.backgroundColor = [UIColor clearColor];
[self addSubview:self.documentTitle];
[self addSubview:self.documentExtension];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
UIEdgeInsets padding = UIEdgeInsetsMake(12, 10, 12, 10);
CGRect layoutRect = UIEdgeInsetsInsetRect(self.bounds, padding);
CGPoint p = layoutRect.origin;
CGSize tmpSize;
CGFloat tfSpaceHorizontal = 6;
CGFloat tfSpaceVertical = 6;
CGSize tmpSizeDocumentExtension = [self.documentExtension sizeThatFits:CGSizeMake(CGRectGetWidth(layoutRect), 1000)];
tmpSize = CGSizeMake(
roundf((CGRectGetWidth(layoutRect) - tfSpaceHorizontal - tmpSizeDocumentExtension.width)),
32
);
self.documentTitle.frame = CGRectMake(
p.x, p.y,
tmpSize.width,
tmpSize.height
);
p.x += tmpSize.width + tfSpaceHorizontal;
CGFloat addedHeight = roundf(tmpSize.height/2 - tmpSizeDocumentExtension.height/2);
addedHeight = addedHeight > 0 ? addedHeight : 0;
p.y += addedHeight;
self.documentExtension.frame = CGRectMake(
p.x,
p.y,
tmpSizeDocumentExtension.width,
tmpSizeDocumentExtension.height
);
}
In iOS 7, every view controller uses full-screen layout, so the coordinate system starts under the status bar, so mind that while positioning your views.
This is mentioned in Apple's iOS 7 UI Transitioning Guide.

Custom MKAnnotaionView, Display title/subtitle Position on Map

1) My annotation shows the title and subtitle of not.
I have already tried a lot, but I can not.
2) If an annotation has been selected, the annotation will be centered in the middle of the window. So the map is moved. Any idea?
3) My Callout button does not work anymore, I've got the # selector (openAnything) but I want to use this function is triggered - (void) mapView: (MKMapView *) mapView annotationView: (MKAnnotationView *) view calloutAccessoryControlTapped: (UIControl *) control {
Enough to ask, here's a video and some source code
http://www.youtube.com/watch?v=Ur1aqeYEFHw&feature=youtube_gdata_player
Thanks
TAPPMapViewControler.m
- (MKAnnotationView *)mapView:(MKMapView *)MapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[TAPPMapAnnotation class]])
{
static NSString *shopAnnotationIdentifier = #"Filiale";
//pinView = (MKPinAnnotationView *)
TAPPMapAnnotationCustom* pinView = (TAPPMapAnnotationCustom*)[self.myMapView dequeueReusableAnnotationViewWithIdentifier:shopAnnotationIdentifier];
[self.myMapView dequeueReusableAnnotationViewWithIdentifier:shopAnnotationIdentifier];
if (pinView == nil)
{
// if an existing pin view was not available, create one
TAPPMapAnnotationCustom *customPinView = [[TAPPMapAnnotationCustom alloc] initWithAnnotation:annotation reuseIdentifier:shopAnnotationIdentifier];
customPinView.image = [UIImage imageNamed:#"map_pin.png"];
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
TAPPMapAnnotation *theAnnotation = view.annotation;
TAPPMapAnnotationDetail *theController = [self.storyboard instantiateViewControllerWithIdentifier:#"MapAnnotationDetail"];
theController.theAnnotationId = theAnnotation.objectId;
[self.navigationController pushViewController:theController animated:YES];
}
TAPPMapAnnotationCustom.h
#import <MapKit/MapKit.h>
#interface TAPPMapAnnotationCustom : MKAnnotationView
#property (strong, nonatomic) UIImageView *calloutView;
#property (strong, nonatomic) UILabel *title;
#property (strong, nonatomic) UILabel *subTitle;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
- (void)animateCalloutAppearance:(BOOL)inAdd;
#end
TAPPMapAnnotationCustom.m
#import "TAPPMapAnnotationCustom.h"
#import "TAPPMapAnnotation.h"
#implementation TAPPMapAnnotationCustom
- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
[super setSelected:selected animated:animated];
if(selected)
{
// Remove Image, because we set a second large one.
self.image = Nil;
UIImage *imageBack = [[UIImage imageNamed:#"map_pin.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 35, 0, 6)];
self.calloutView = [[UIImageView alloc]initWithImage:imageBack];
[self.calloutView setFrame:CGRectMake(0,0,0,0)];
[self.calloutView sizeToFit];
[self addSubview:self.calloutView ];
// Callout Button
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(openAnything) forControlEvents:UIControlEventTouchUpInside];
rightButton.frame = CGRectMake(0
, ((self.calloutView.frame.size.height-6) / 2)-(rightButton.frame.size.height / 2)
, rightButton.frame.size.width
, rightButton.frame.size.height);
self.rightCalloutAccessoryView = rightButton;
self.rightCalloutAccessoryView.hidden = YES;
self.rightCalloutAccessoryView.alpha = 0;
[self addSubview:self.rightCalloutAccessoryView];
// Start Annimation
[self animateCalloutAppearance:YES];
} else {
//Start Annimation and Remove from view
[self animateCalloutAppearance:NO];
}
}
- (void)didAddSubview:(UIView *)subview{
if ([[[subview class] description] isEqualToString:#"UICalloutView"]) {
for (UIView *subsubView in subview.subviews) {
if ([subsubView class] == [UIImageView class]) {
UIImageView *imageView = ((UIImageView *)subsubView);
[imageView removeFromSuperview];
}else if ([subsubView class] == [UILabel class]) {
UILabel *labelView = ((UILabel *)subsubView);
[labelView removeFromSuperview];
}
}
}
}
- (void)animateCalloutAppearance:(BOOL)inAdd {
if (inAdd == YES) {
self.rightCalloutAccessoryView.hidden = NO;
[UIView animateWithDuration:0.4 delay:0 options: UIViewAnimationOptionTransitionNone
animations:^{
self.calloutView.frame = CGRectMake(self.calloutView.frame.origin.x
, self.calloutView.frame.origin.y
, self.calloutView.frame.size.width+150
, self.calloutView.frame.size.height);
self.rightCalloutAccessoryView.alpha = 1;
self.rightCalloutAccessoryView.frame = CGRectMake(self.calloutView.frame.size.width - (self.rightCalloutAccessoryView.frame.size.width)
, self.rightCalloutAccessoryView.frame.origin.y
, self.rightCalloutAccessoryView.frame.size.width
, self.rightCalloutAccessoryView.frame.size.height);
} completion:^(BOOL finished){ }];
} else {
[UIView animateWithDuration:0.4 delay:0 options: UIViewAnimationOptionTransitionNone
animations:^{
self.rightCalloutAccessoryView.alpha = 0;
self.rightCalloutAccessoryView.frame = CGRectMake(0
, self.rightCalloutAccessoryView.frame.origin.y
, self.rightCalloutAccessoryView.frame.size.width
, self.rightCalloutAccessoryView.frame.size.height);
self.calloutView.frame = CGRectMake(self.calloutView.frame.origin.x
, self.calloutView.frame.origin.y
, self.calloutView.frame.size.width-150
, self.calloutView.frame.size.height);
} completion:^(BOOL finished){
self.image = [UIImage imageNamed:#"map_pin.png"];
[self.calloutView removeFromSuperview];
[self.rightCalloutAccessoryView removeFromSuperview];
}];
}
}
#end
Your annotation class needs to have a subtitle attribute, yours has subTitle.
If calloutAccessoryControlTapped is not being called it is usually a sign your MKMapview's delegate has not been set. However you're only setting the accessory button when it gets selected. Do you have a good reason for that? Since the callout window won't be visible until it is selected, I would advise you to set the accessory button in viewForAnnotation and let it appear when the callout window does.
I fix the first one:
TAPPMapAnnotation *theAnnotation = (TAPPMapAnnotation *)self.annotation;
self.title = [[UILabel alloc]init];
self.title.font = [UIFont systemFontOfSize:12.0];
self.title.textColor = [UIColor whiteColor];
self.title.backgroundColor = [UIColor clearColor];
self.title.text = theAnnotation.title;
[...]
[self.theView addSubview:self.title];

Change Overlay Alpha based on MapType selection

I would like to know if its possible to change the map overlay alpha based on selecting the maptype here is my code I thought might work but it doesn't seem to. Can anyone provide some incite?
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay{
TileOverlayView *view = [[TileOverlayView alloc] initWithOverlay:overlay];
if(mapview.mapType == MKMapTypeHybrid) {
view.tileAlpha = 0.55;
} else if(mapview.mapType == MKMapTypeSatellite) {
view.tileAlpha = 0.0;
} else {
view.tileAlpha = 0.75;
}
return [view autorelease];
}
This code works fine
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
MKCircleView *circleView = [[MKCircleView alloc] initWithCircle:overlay];
CGFloat alpha;
if (mapView.mapType == MKMapTypeStandard) {
alpha = 0.5f;
} else {
alpha = 1.0f;
}
circleView.fillColor = [[UIColor blackColor] colorWithAlphaComponent:alpha];
return circleView;
}
But in mapView:viewForOverlay you set alpha based on current map type. To change alpha when map change map type you need to observe mapType property using KVO. So when map type is changing you just set new alpha for all overlays. To get view for overlay use
[mapView viewForOverlay:(id<MKOverlay>)overlay];

start at the top of the page when changing page

ı have a problem about scrollview.
my project about a newspaper.my problem about : I want to start at the
top of the page when changing page.
scrollview have 8 news.ı want to beginning at the top of the text on
the page when change 2. or 3. or.. news..
please help me about it.because ı need to deliver the project on Monday.for this reason ı
must do today or tomorrow.
code of project in here
myScrollview = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
myScrollview.pagingEnabled = YES;
myScrollview.scrollEnabled =YES;
myScrollview.clipsToBounds = NO;
myScrollview.indicatorStyle = UIScrollViewIndicatorStyleWhite;
myScrollview.showsHorizontalScrollIndicator = YES;
myScrollview.backgroundColor = [UIColor blackColor];
myScrollview.delegate = self;
NSInteger viewcount=4;
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"photo1.png"],[UIImage imageNamed:#"photo2.png"],[UIImage imageNamed:#"photo3.png"],[UIImage imageNamed:#"photo4.png"],nil];
for (int i = 0; i <viewcount; i++)
{
CGFloat x = i * self.view.frame.size.width;
subView = [[UIScrollView alloc]initWithFrame:CGRectMake(x, 0, self.view.frame.size.width, self.view.frame.size.height)];
[subView setBackgroundColor:[UIColor blackColor]];
[subView setCanCancelContentTouches:NO];
subView.clipsToBounds = NO; // default is NO, we want to restrict drawing within our scrollview
subView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
aImageView = [[UIImageView alloc ] initWithImage:[images objectAtIndex:i]];
aImageView.frame=CGRectMake(0, 0, 320, 900);
[aImageView setTag:viewcount];
[subView addSubview:aImageView];
[subView setContentSize:CGSizeMake(aImageView.frame.size.width, subView.frame.size.height)];
subView.minimumZoomScale = 1;
subView.maximumZoomScale = 9;
subView.delegate = self;
[subView setScrollEnabled:YES];
subView.contentSize = aImageView.frame.size;
[myScrollview addSubview:subView];
}
myScrollview.contentSize = CGSizeMake(self.view.frame.size.width*viewcount,self.view.frame.size.height);
[self.view addSubview:myScrollview];
https://biliyomusunuz.com

Resources