insertText not working in UITextView with iOS6? - uitextview

I have developped a litle function to insert text in UITextView and scroll down automatically. It works fine with iOS 5 but since i have updated Xcode to Xcode 4.5 with iOS6, this method no longer works.
Could you help me ?
Here is this method :
- (void) insertTextInAPP : (UITextView*) tv : (NSString*) s {
NSRange range = {[tv.text length], 0};
[tv setSelectedRange:range];
[tv insertText:s];
[tv insertText:#"\n"];
range.location = [tv.text length];
[tv scrollRangeToVisible:range];
}
And i use this function like this :
NSString *newEventString = [[NSString alloc] initWithFormat : #"Test"];
[self insertTextInAPP:self.outPutTextView: newEventString];

It works just fine here (iOS 6, Xcode 5.5). Of course, I needed to change (UITextView) tv to (UITextView*) tv and "Test" to #"Test", but other than that it was alright.
What happens when you try it?

Related

iOS 9 UINavigation bar content is not centred after rotation in iOS 9?

I noticed a bug in iOS 9, or may be I am not using something correctly.
In the following code in an empty project targeted for iPhone :
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Show" style:UIBarButtonItemStylePlain target:self action:#selector(test:)];
self.navigationItem.rightBarButtonItem = anotherButton;
self.navBar.items = #[self.navigationItem];
I added a custom button to a navigation bar property. I noticed that after rotation from portrait to landscape, the button moves down and it is not centered correctly in the navigation bar.
Portrait Screen
Landscape Screen
This code works fine if I compile for iOS 8.4 for example, but not on iOS 9.
Has anyone encountered this?
Thanks!
I've seen something similar on the iPad. When I start the app in portrait, then rotate to landscape, the View Controller its navigationItem.titleView doesn't align correctly anymore. I simply reset it after rotation as follows in Swift:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition(nil) { (coordinator) -> Void in
self.navigationItem.titleView = someView
}
}
Swift 3:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: nil) { (coordinator) -> Void in
self.navigationItem.titleView = self.someView
}
}
I have managed to fix the problem with custom navigation bar class with and overridden method:
-(void) layoutSubviews
{
[super layoutSubviews];
for (UIView *view in self.subviews)
{
if ([view isKindOfClass:[UIView class]] ||
[view isKindOfClass:[UIButton class]] ||
[view isKindOfClass:[UISearchBar class]] ||
[view isKindOfClass:[UILabel class]])
{
CGRect frame = view.frame;
frame.origin.y = (self.frame.size.height - frame.size.height) / 2.f;
view.frame = frame;
}
}
}
Other type of view classes can be added in the if statement. Its not the cleanest solution, but it will do for now.

Show UIAlertController over keyboard

In iOS 8 and lower show a UIActionSheet when keyboard is presented will present the action sheet over the keyboard. With iOS 9 this is no longer the case.
In my app we have a chat functionality and want the show a action over the keyboard. We used to use UIActionSheet which worked fine until iOS 8. In iOS 9 the action sheet is present behind the keyboard. I've tried both UIActionSheet and UIAlertController.
What we want is a action sheet like in messages.app
I've tried placing the action sheet in it own window and overriding canBecomeFirstResponder which just made the keyboard disappear.
I have implemented exactly this in our app. The trick is to have the alert controller appear on a different window. This is how the UIActionSheet implementation does it, and works great on iOS 8, but on 9, Apple has moved the keyboard implementation to a window which has a very high window level (10000000). The fix is to give your alert window an even higher window level (as a custom double value, not using the provided constants).
When using a custom window which will have transparency, make sure to read my answer here, regarding background color, to prevent window becoming black during rotation transitions.
_alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_alertWindow.rootViewController = [UIViewController new];
_alertWindow.windowLevel = 10000001;
_alertWindow.hidden = NO;
_alertWindow.tintColor = [[UIWindow valueForKey:#"keyWindow"] tintColor];
__weak __typeof(self) weakSelf = self;
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Test" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
weakSelf.alertWindow.hidden = YES;
weakSelf.alertWindow = nil;
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Test" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
weakSelf.alertWindow.hidden = YES;
weakSelf.alertWindow = nil;
}]];
[_alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
The answer supplied by Leo is broken as of iOS 11, because Apple now prevents you from setting a windowLevel above 10000000. A fix is to implement a custom UIWindow and override the windowLevel receiver:
#interface TopWindow : UIWindow #end
#implementation TopWindow
- (UIWindowLevel) windowLevel {
return 20000000.000;
}
#end
// usage:
UIWindow* w = [[TopWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
w.rootViewController = [UIViewController new];
w.hidden = NO;
[w.rootViewController presentViewController:yourActionSheetController animated:YES completion:nil];
This approach should be backwards compatible, but haven't tested all known versions. Happy hacking!
Based on Leo Natan's answer, I've created a Swift extension for presenting an alert sheet over the keyboard.
In my brief testing, the alertWindow is deallocated after the alert is dismissed, I believe because there's no strong reference to it outside of the alert. This means there's no need to hide or deallocate it in your UIAlertActions.
extension UIAlertController {
func presentOverKeyboard(animated: Bool, completion: (() -> Void)?) {
let alertWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
// If you need a white/hidden/other status bar, use an appropriate VC.
// You may not need a custom class, and you can just use UIViewController()
alertWindow.rootViewController = whiteStatusBarVC()
alertWindow.windowLevel = 10000001
alertWindow.hidden = false
// Set to a tint if you'd like
alertWindow.tintColor = UIColor.greenColor()
alertWindow.rootViewController?.presentViewController(self, animated: animated, completion: completion)
}
}
private class whiteStatusBarVC: UIViewController {
private override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
use UIAlertController instead of UIActionSheet

Issue in showing my UIWebview in IOS 7 properly

In my app i have a UIWebview in which all the activity is taking place.
The app works perfect on ios6 but with iOS 7 my UIwebview content is colliding with the status bar.
Is there a way i can set the view for my UIWindow to show this properly.
if([[[UIDevice currentDevice] systemVersion] integerValue] >= 7) {
if (self.window.rootViewController.view.frame.origin.y <=0) {
screenBounds = CGRectMake(0, 20, self.window.bounds.size.width, self.window.bounds.size.height-20);
}
}
self.window.rootViewController = self.viewController;
Thanks,
Try:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
in the viewDidLoad method of your view controller.

iOS 7 UIWebView doesn't load webpage

My app uses UIWebview, and it works well in iOS 5 and iOS 6. However, it doesn't load the webpage in iOS 7 when I build in Xcode 5 and run the same code.
- (void)webViewDidFinishLoad:(UIWebView *)webView {}
- (void)webViewDidStartLoad:(UIWebView *)webView {}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {}
All delegate function is not called. But I do set delegate in xib file and code
self.theWebView.delegate = self;
I didn't find any information via google. Thank you for your help.
I moved the loadRequest method to the completion handler of a presentViewController and it works in iOS 5, 6 and 7:
[self presentViewController:gwvc animated:YES completion:^(void){
[gwvc.wv loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.walkjogrun.net/about/eukanuba.html"]]];
}];
I found the root cause.
maybe I incorrectly used UIWebView, but it works in iOS5 and iOS6.
I don't know why it works in earlier iOS versions...
Moreover, it works in iOS7 when I build code with SDK 6.1.
Here's my old code.
RechargeWebPageViewController *webPageViewController;
webPageViewController = [[ RechargeWebPageViewController alloc] initWithNibName:#"WebPage" bundle:nil];
if (webPageViewController != nil) {
webPageViewController.hidesBottomBarWhenPushed = YES;
webPageViewController.delegate=self;
[self.navigationController pushViewController:webPageViewController animated:YES];
NSURL *url = [NSURL URLWithString:#"https://xxx.php"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url];
[webPageViewController loadRequest:request];
[request release];
}
I moved the loadRequest from the viewDidLoad method to the ViewWillAppear method, then it worked.
I think maybe UIWebView is not initialized correctly in my old code for iOS7.

iPhone-5 compatible issue

I had developed an ios app for ios 4.0.That was navigation based application.Now I want it also support for iPhone-5 I think I changed xib after checking device version,I am facing problem xib is changed but it's view Height is not changed.How it can possible if some else face this problem please share ideas with me.Thanks.
IN APP Delegate:-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
//----------------HERE WE SETUP FOR IPHONE 4/4s/iPod----------------------
if(iOSDeviceScreenSize.height == 480){
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_4inch" bundle:nil];
NSLog(#"iPhone 4: %f", iOSDeviceScreenSize.height);
}
//----------------HERE WE SETUP FOR IPHONE 5----------------------
if(iOSDeviceScreenSize.height == 568){
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_5inch" bundle:nil];
NSLog(#"iPhone 5: %f", iOSDeviceScreenSize.height);
}
return YES;
}
Its Works !!!!!!
Set iOS 6 as the Base SDK and use the Auto Layout feature to make screens that can scale for all type of screens. You'll need Xcode 4.5 to do this.
Get started with Auto Layout here:
http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2
If you still want to support iOS 4.0, have separate .xib files for different screen sizes and load them appropriately at launch.
To load different nib files based on your screen size, in your app delegate, you will need to add/replace the following code in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_4inch" bundle:nil];
} else {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
}
where ViewController_4inch is the name of the nib file that is designed for iPhone 5 screen

Resources