I resently faced some strange issue on IOS 6.0 related to MKAnnotation (part of MKMap Kit)
May be some of you fased the same, or have idea or advise how to skip/avoid/solve it.
Here it is
I need some Pins on my map with callout bubbles (contains titles & subtitles nothing more)
When i pressing on it callout starts. Due to user comfort I've added observer to center pin:
(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{
NSString *action = (NSString*)context;
if([[change valueForKey:#"new"] intValue] == 1 && [action isEqualToString:#"GMAP_ANNOTATION_SELECTED"]) {
if ([((MKAnnotationView*) object).annotation isKindOfClass:[CustomPlacemark class]]) {
CustomPlacemark *place = ((MKAnnotationView*) object).annotation;
[mapView setCenterCoordinate:place.coordinate animated:YES];
}
}
}
On ios 5.1 or above everything looks & works fine (pin centering after press, callout bubbles shows above centered horizontally), but on IOS 6.0 behavior is strage, pin centering as well, but callout bubble not, even if it's width enough to fill screen horizontally it could appear partially beyond screen.
Haven't found any solution or options to manually setup appearance behavior. Have any advices?
Thx for further answers, and sorry for my English.
Related
Anyone knowns how to set round corner to the video frame using AVPlayer?
I'm trying doing this:
- (void)loadVideoWithPlayer:(AVPlayer*)playerVideo
{
dispatch_async(dispatch_get_main_queue(), ^{
AVPlayerLayer *avLayer = [AVPlayerLayer playerLayerWithPlayer: playerVideo];
[avLayer setCornerRadius:20];
[avLayer setMasksToBounds:YES];
[self.playerViewController setPlayer:playerVideo];
[self insertSubview:self.playerViewController.view belowSubview:self.interactView];
[self.playerViewController.player play];
});
}
but it's not working. I can't set round corners to the AVPlayer.playerViewController.view because the video frame could be different.
I was just able to do this. The change could even be animatable, from no rounder corners to rounded corners.
I didn't do anything much different from you. Using iOS 10 at the moment. (Confirmed working on iOS 9.3.5 device also.)
self.viewVideo?.layer.masksToBounds = SHOW ? true : false
self.viewVideo?.layer.cornerRadius = SHOW ? 10 : 0
I should perhaps note that the viewVideo is a subclass of UIView. The only real change there is the layerClass being returned as AVPlayerLayer.self
override static var layerClass: AnyClass {
return AVPlayerLayer.self
}
So btw I do not use AVPlayerViewController etc. I just add my subclass of UIView to my usual UIViewController's view.
I have an MKMapView with an iAd banner on top. Due to this iAd Banner covering the MKMapView's legal label, it is moved. The following code is performed in viewDidLayoutSubviews:
NSLog(#"ViewDidLayoutSubviews called");
UILabel *attributionLabel = [self.mapView.subviews objectAtIndex:1];
if (adBannerViewFrame.origin.y < attributionLabel.frame.origin.y) {
NSLog(#"Banner Y coordinate: %f", adBannerViewFrame.origin.y);
CGRect legalFrame = attributionLabel.frame;
legalFrame.origin.y -= IAD_BANNER_HEIGHT;
attributionLabel.frame = legalFrame;
NSLog(#"Legal y: %f", legalFrame.origin.y);
NSLog(#"Legal x: %f", legalFrame.origin.x);
NSLog(#"Legal width: %f", legalFrame.size.width);
NSLog(#"Legal height: %f", legalFrame.size.height);
}
When I switch from the View Controller containing the map to another VC and back again, the code above works perfect, regardless of orientation; however, when rotating the devices without switching VCs, the legal label disappears on rotation and don't come back until I switch back and fourth between VCs again. The NSLogs print out the exact same for both rotation and VC switching:
ViewDidLayoutSubviews called
Banner Y coordinate: 902/646(rotation dependent)
Legal x: 882/626(rotation dependent)
Legal y: 11
Legal width: 48
Legal height 11
Despite everything looking the same, the label is gone after rotating (not sure if it is moved out of the view or if it actually disappears)
The iAd Banner is reloaded in ViewDidAppear (which is called when VCs are switched back and fourth). However, since the NSLogs print the same for both scenarios, I cannot see how it should make any difference. To be sure, I tried to reload the iAd Banner in ViewDidLayoutSubviews as well, with no different result than before. Anyone experienced anything similar or know how to fix this?
For anyone encountering the same issue, I found a solution. The workaround was to schedule a timer with 0 seconds and have the timer call the method executing the code above.
[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(test) userInfo:nil repeats:NO];
I assume that something was not completely finished when viewDIDlayoutSubviews was called and that adding a timer (which is not 100 % accurate and will therefore not start immediately), allowed the unknown remaining stuff to complete before the code in the question was executed.
I have been unable to find a solution to this problem anywhere.
I am using Xcode 4.5 to write an iOS 6 app using storyboards. It uses a Navigation Controller to jump between several View Controllers with Navigation Bars, including a few that use a UIWebView to display a website. I have added code to the AppDelegate and various ViewController files to restrict the view to Portrait for most scenes in the app (since they really won't look good otherwise), but to allow Landscape view for the websites. And the Info.plist is configured allow all 4 orientations.
Everything works fine in the UIWebView scene; including rotation, scrolling and zooming - except for one thing: when I rotate from Portrait to Landscape, the horizontal dimension of the website stays locked at the horizontal dimension for the Portrait view - resulting in a large white space to the right of the website in the scene (see images below). I fixed a small (1/4") white space at the top of the UIWebView by selecting Layout: Wants Full Screen under View Controller in the Attributes Inspector. But I can't fix this.
I can supply relevant code or Storyboard settings if necessary. Can anyone help? Thank you.
I solved adding this code, when application loads on viewDidLoad method:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
Then add this to your view controller:
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
_displayWeb.frame = CGRectMake (0, 0, 768, 1024);
break;
case UIDeviceOrientationPortraitUpsideDown:
_displayWeb.frame = CGRectMake (0, 0, 768, 1024);
break;
case UIDeviceOrientationLandscapeLeft:
_displayWeb.frame = CGRectMake (0, 0, 1024, 768);
break;
case UIDeviceOrientationLandscapeRight:
_displayWeb.frame = CGRectMake (0, 0, 1024, 768);
break;
default:
break;
};
}
_displayWeb is your IBOutlet UIWebView, by the way this is using Xcode 4.6.1
Background
So, with iOS 6 an UITextView can take an attributedString, which could be useful for Syntax highlighting.
I'm doing some regex patterns in -textView:shouldChangeTextInRange:replacementText: and oftentimes I need to change the color of a word already typed. I see no other options than resetting the attributedText, which takes time.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
//A context will allow us to not call -attributedText on the textView, which is slow.
//Keep context up to date
[self.context replaceCharactersInRange:range withAttributedString:[[NSAttributedString alloc] initWithString:text attributes:self.textView.typingAttributes]];
// […]
self.textView.scrollEnabled = FALSE;
[self.context setAttributes:self.defaultStyle range:NSMakeRange(0, self.context.length)];
[self refresh]; //Runs regex-patterns in the context
textView.attributedText = self.context;
self.textView.selectedRange = NSMakeRange(range.location + text.length, 0);
self.textView.scrollEnabled = TRUE;
return FALSE;
}
This runs okayish on the simulator, but on an iPad 3 each -setAttributedText takes a few hundreds of milliseconds.
I filed a bug to Apple, with the request of being able to mutate the attributedText. It got marked as a duplicate, so I cannot see what they're saying about this.
The question
The more specific question:
How can I change the color of certain ranges in a UITextView, with a large multicolored text, with good enough performance to do it in every shouldReplaceText...?
The more broad question:
How do you do syntax highlighting with a UITextView in iOS 6?
I encountered the same problem for my application Zap-Guitar (No-Strings-Attached) where I allow users to type/paste/edit their own songs and the app highlights recognized chords.
Yes it is true apple uses an html writer and parser to display the attributed text. A wonderful explanation of behind the scene can be found here: http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/
The only solution I found for this problem is not to use attributed text which is an overkill for syntax highlighting.
Instead I reverted to the good old UITextView with plain text and added buttons to the text view where highlighted was needed. To compute the buttons frames I used this answer: How to find position or get rect of any word in textview and place buttons over that?
This reduced CPU usage by 30% (give or take).
Here is a handy category:
#implementation UITextView (WithButtons)
- (CGRect)frameForTextRange:(NSRange)range {
UITextPosition *beginning = self.beginningOfDocument;
UITextPosition *start = [self positionFromPosition:beginning offset:range.location];
UITextPosition *end = [self positionFromPosition:start offset:range.length];
UITextRange *textRange = [self textRangeFromPosition:start toPosition:end];
CGRect rect = [self firstRectForRange:textRange];
return [self convertRect:rect fromView:self.textInputView];
}
#end
The attributedText accessors have to round-trip to/from HTML, so it's really non-optimal for a syntax-highlighted text view implementation. On iOS 6, you'll probably want to use CoreText directly.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UIWebView on iPad size
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *naviController = [[UINavigationController alloc]init];
[self.view addSubview:naviController.view];
}
If I add navigation controller in the view, it appears about 20 pixels below status bar.
I want it appears just below status bar. How do I fix this?
I've experienced this same issue.
This discussion was helpful: UIWebView on iPad size
Tony's answer helped me discover this trick:
naviController.view.frame = self.view.bounds;
Turns out setting the view height fixes this problem. You can do it in the nib (xib) file or progammatically when creating the view setting the view.frame = CGRect(0, 0, 320.0 460.0); or whatever it's supposed to be (in your case it looks like it should be 460.0 since you have the status bar on).
The main point is that if the view size is smaller than the height of the screen, there are no guarantees where your controls will show up.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect frame = CGRectMake(0, 0, 320.0, 480.0);
viewController.view.frame = frame;
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
I changed like above. It works. So far so good. If height was 460, there would have been blank line at the bottom. View's absolute coordinate is (0, 20). So, Navigation bar's coordinate is (0, 40). I think that was the problem. I will encounter another problem.
Maybe there is way to change coordinate before displaying navigation view. Thank you.