Force view controller to reload to refresh UIAppearance changes - ios

I have been searching for quite a while and can't find an answer. I am working on an iOS app and have a modal settings page that appears on the tap of a button and returns with a segue.
One of the options I would like to implement is a color scheme setting. I really want to avoid manually changing the color for every element on the page.
Apple has a UIAppearance protocol for this sort of thing (so I can set the text color of all buttons, etc.
Their documentation says:
Note: iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.
My question is how to do this. I have tried calling viewWillAppear and setNeedsDisplay without luck.

Try to use this snippet :
NSArray *windows = [UIApplication sharedApplication].windows;
for (UIWindow *window in windows) {
for (UIView *view in window.subviews) {
[view removeFromSuperview];
[window addSubview:view];
}
}
http://snipplr.com/view/75259/refresh-uiappearance-after-application-loaded/
It works perfect for me after changing app theme using UIAppearance

Please note that the top answer will have adverse effects on your system keyboard behavior.
It turns out that iOS creates a new system window with UITextEffectsWindow class under the hood whenever the keyboard is displayed. If you remove it, your keyboard behavior may be negatively affected. For example, the input accessory views will be detached from the keyboard and will not be visible, except for brief flashes in the navigation controllers.
You can workaround this issue by using an additional check, like so:
for window in UIApplication.shared.windows {
// Whenever a system keyboard is shown, a special internal window is created in application
// window list of type UITextEffectsWindow. This kind of window cannot be safely removed without
// having an adverse effect on keyboard behavior. For example, an input accessory view is
// disconnected from the keyboard. Therefore, a check for this class is needed. In case this class
// that is indernal is removed from the iOS SDK in future, there is a "fallback" class check on
// NSString class that always fails.
if !window.isKind(of: NSClassFromString("UITextEffectsWindow") ?? NSString.classForCoder()) {
window.subviews.forEach {
$0.removeFromSuperview()
window.addSubview($0)
}
}
}
Note that the UITextEffectsWindow is internal and may change in the future. This is why I do not unwrap the variable using ! but provide a fallback negative NSString class instead (no type of window is of NSString class).
Note: For simple apps, you can probably live by using UIApplication.shared.keyWindow for the workaround.

Specifically, to get the current view and it's superview, try:
UIView *currentview = self.window.rootViewController.view;
UIView *superview = currentview.superview;
[currentview removeFromSuperview];
[superview addSubview:currentview];
Works for me.

For Swift:
let windows = UIApplication.sharedApplication().windows
for window in windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
}

For Swift 3.0.2:
for window in UIApplication.shared.windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
// update the status bar if you change the appearance of it.
window.rootViewController?.setNeedsStatusBarAppearanceUpdate()
}

Here's a Swift 5 one-liner:
UIApplication.shared.windows.forEach { $0.subviews.forEach { $0.removeFromSuperview(); self.window?.addSubview($0) }}

Try
[self.yourView removeFromSuperView];
[self addSubView:yourView];

For swift 4:
let windows = UIApplication.shared.windows
for window in windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
}

The most answers are very good and perfect for changing language from LTR to RTL but sometimes tab bar navigation titles and navigation bar titles will not get translated. I fixed the problem with the following code
if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
window.rootViewController = TabNavigationController()
let tab = window.rootViewController as? UITabBarController
tab?.selectedIndex = 3
window.makeKeyAndVisible()
}

Objective c
self.view.window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
I use this code if I want change overrideUserInterfaceStyle in all view controllers

Related

Strange UISearchDisplayController view offset behavior in iOS 7 when embedded in navigation bar

I am building an iOS 7-only app. I am trying to set a UISearchDisplayController into the navigation bar.
I have it set up like this: In the storyboard, I added a "Search Bar and Search Display Controller" to my view controller's view, and set it at (0,0) relative to the top layout guide. I set constraints to pin to left, top and right. (I played with the constraints, i removed them completely, it doesn't matter) On top of that I have my Table view. When I added the search bar to the view in the storyboard, it automatically setup outlets for searchDisplayController and searchBar delegate. In code I have self.searchDisplayController.displaysSearchBarInNavigationBar = YES; I have two problems:
1) Without any buttons showing for the search bar (Interface builder -> select search bar -> Options: none selected) the search bar is in the middle of the screen:
If I click on the navigation bar, it starts editing the search bar:
notice also that the dark overlay appears to be offset from the navigation bar. It seems to me that the space is the same height as the navigation bar. Like it has been shifted down by that much. Also, when it displays the search results, the top of the content view is shifted down by the same amount (more pictures follow), which brings me to the second problem.
2) I messed around with it for a while and decided to check the option to have it show the cancel button. Now I have the search bar embedded in the nav bar correctly, but the overlay is still shifted down:
Again, when the search results table view appears, it is shifted down by the same amount (notice the scroll bar on the right side):
Even more bizarrely, I set a border on the search display controller's tableview layer, and it appears correct:
I have never used the UISearchDisplayController before and I unfamiliar with how to set it up, but functionally it works fine. I have read some other similar posts but the only advice is to hack it up by adjusting frames and setting manual offsets. I'd prefer to know what is causing this, is it a bug? Something I'm doing wrong? If it's a bug I can wait for a fix. It seems like such a basic thing that a thousand people must have done without any problem so I feel like I'm not setting it up correctly somehow. Thanks for you input.
I remember running into the same exact problem that you are observing.There could be a couple of solutions you can try.
If you are using storyboards
You should click on the view controller or TableView Controller which you have set up for your tableview and go to its attribute inspector and look under ViewController section and set the Extend Edges section to be under Top Bars.
If you are not using storyboards you can manually set the settings using the viewcontrollers edgesForExtendedLayout property and that should do the trick. I was using storyboards.
In my case, using storyboards, I had to check both Under Top Bars and Under Opaque Bars and leave Under Bottom Bars unchecked.
In my case, I actually had to uncheck all the Extended Edges boxes (essentially the same as programmatically setting Extended Edges to UIRectEdgeNone I believe) in my Storyboard in order to stop my search bar from offsetting itself. Thank you guys!
definesPresentationContext = true
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = true
searchController.searchBar.searchBarStyle = UISearchBarStyle.Prominent
self.tableView.tableHeaderView = searchController.searchBar
definesPresentationContext = true
or see UISearchBar presented by UISearchController in table header view animates too far when active
My problem was just Adjust scroll view inserts. After change to false I didn't have problem
I had a same problem. And I solve this issue with adding view object under the tableview.
Add new ViewController on the Storyboard
Drag TableView to the new VC
Drag Table Cell to the TableView
Make a Connection for TableView DataSource, TableView Delegate to the new VC
I had very similar behavior happening. For me, the solution was to uncheck Extend Edges Under Top Bar in the storyboard settings for the parent view controller (I've turned off transparent navbars, not sure if that effects anything). If you're not using storyboard, you have to set [UIViewController edgesForExtendedLayout].
From the Apple docs:
This property is only applied to view controllers that are embedded in containers, such as UINavigationController or UITabBarController. View controllers set as the root view controller do not react to this property. Default value is UIRectEdgeAll.
Unfortunately none of the above solutions worked for me, I'm using a UITableViewController.
This link helped:
http://petersteinberger.com/blog/2013/fixing-uisearchdisplaycontroller-on-ios-7/
I put the code below for convenience:
static UIView *PSPDFViewWithSuffix(UIView *view, NSString *classNameSuffix) {
if (!view || classNameSuffix.length == 0) return nil;
UIView *theView = nil;
for (__unsafe_unretained UIView *subview in view.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:classNameSuffix]) {
return subview;
}else {
if ((theView = PSPDFViewWithSuffix(subview, classNameSuffix))) break;
}
}
return theView;
}
- (void)correctSearchDisplayFrames {
// Update search bar frame.
CGRect superviewFrame = self.searchDisplayController.searchBar.superview.frame;
superviewFrame.origin.y = 0.f;
self.searchDisplayController.searchBar.superview.frame = superviewFrame;
// Strech dimming view.
UIView *dimmingView = PSPDFViewWithSuffix(self.view, #"DimmingView");
if (dimmingView) {
CGRect dimmingFrame = dimmingView.superview.frame;
dimmingFrame.origin.y = self.searchDisplayController.searchBar.frame.size.height;
dimmingFrame.size.height = self.view.frame.size.height - dimmingFrame.origin.y;
dimmingView.superview.frame = dimmingFrame;
}
}
- (void)setAllViewsExceptSearchHidden:(BOOL)hidden animated:(BOOL)animated {
[UIView animateWithDuration:animated ? 0.25f : 0.f animations:^{
for (UIView *view in self.tableView.subviews) {
if (view != self.searchDisplayController.searchResultsTableView &&
view != self.searchDisplayController.searchBar) {
view.alpha = hidden ? 0.f : 1.f;
}
}
}];
}
// This fixes UISearchBarController on iOS 7. rdar://14800556
- (void)correctFramesForSearchDisplayControllerBeginSearch:(BOOL)beginSearch {
if (PSPDFIsUIKitFlatMode()) {
[self.navigationController setNavigationBarHidden:beginSearch animated:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[self correctSearchDisplayFrames];
});
[self setAllViewsExceptSearchHidden:beginSearch animated:YES];
[UIView animateWithDuration:0.25f animations:^{
self.searchDisplayController.searchResultsTableView.alpha = beginSearch ? 1.f : 0.f;
}];
}
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
[self correctFramesForSearchDisplayControllerBeginSearch:YES];
}
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
[self correctSearchDisplayFrames];
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
[self correctFramesForSearchDisplayControllerBeginSearch:NO];
}
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
// HACK: iOS 7 requires a cruel workaround to show the search table view.
if (PSPDFIsUIKitFlatMode()) {
controller.searchResultsTableView.contentInset = UIEdgeInsetsMake(self.searchDisplayController.searchBar.frame.size.height, 0.f, 0.f, 0.f);
}
}
Go to storyboard.
Click on the view controller.
Go to attribute inspector under the ViewController section.
Set the Extend Edges section to be Under Top Bars and Under Opaque Bars.
Make sure to un-check Under Bottom Bars.

How can I modify PKRevealController slide-out menus to deal with iOS 7?

I have an application using PKRevealController which implements a slide-out menu similar to the ones in the popular Facebook and GMAIL apps on iOS. The app is built in XCode 5, and runs on iOS 6 and iOS 7. I need to figure out how to have it work sanely in both places, so a simple .XIB hack that makes it look okay in iOS 7 but makes it look worse in iOS 6 is not okay.
The code works great for iOS 6, where the status bar is opaque and the top view is not alpha-blended with the status bar.
However, on iOS 7, just for example, I have created this view in my .xib file, here is how it appears running in ioS 6 simulator, shown here with the slide out menu opened:
The same .xib file running on ios 7, when the slide-out menu open, the top of the slide out menu's .xib content is now under the status bar, as Apple said it would be in their ios 7 transition guide:
The class I need to modify in PKRevealController is probably the presenting view controller that is creating and presenting the contained view, the contained view is called PKRevealControllerContainerView, I think. I think I probably need to create
some kind of view hierarchy like this:
[ Outermost View container
[ some kind of blob to occupy the header area ]
[ the client view I want to appear the way it did in iOS 6]
]
I've been reading around, and there may be much simpler approaches, but I don't quite understand them, approaches like adding properties to my info.plist, like View controller-based status bar appearance = YES. I tried that it did not have the desired effect.
How do I go about fixing this? I have read the Fine Guide published by Apple and it has not provided code, only general guidance like this page on the status bar.
It's easy to replicate this problem, just clone the git repo https://github.com/pkluz/PKRevealController, build and run.
The code that brings up the pop-up view looks like this:
- (void)addLeftViewControllerToHierarchy
{
if (self.leftViewController != nil && ![self.childViewControllers containsObject:self.leftViewController])
{
[self addChildViewController:self.leftViewController];
self.leftViewContainer.viewController = self.leftViewController;
if (self.leftViewContainer == nil)
{
self.leftViewContainer = [[PKRevealControllerContainerView alloc] initForController:self.leftViewController shadow:NO];
self.leftViewContainer.autoresizingMask = [self autoresizingMaskForLeftViewContainer];
}
self.leftViewContainer.frame = [self leftViewFrame];
[self.view insertSubview:self.leftViewContainer belowSubview:self.frontViewContainer];
[self.leftViewController didMoveToParentViewController:self];
}
}
The above is invoked by PKRevealController.m, like this:
- (void)showLeftViewControllerAnimated:(BOOL)animated
completion:(PKDefaultCompletionHandler)completion
{
__weak PKRevealController *weakSelf = self;
void (^showLeftViewBlock)(BOOL finished) = ^(BOOL finished)
{
[weakSelf removeRightViewControllerFromHierarchy];
[weakSelf addLeftViewControllerToHierarchy]; // HELLO LEFT Slide-out menu.
....
Is there a better approach than my idea? Did Apple provide some way to make this easy or does trying to support iOS 6 and iOS 7 in a single codebase leave me doing hacks like the above I'm considering?
Here, for instance, is a really ugly hack where I don't bother placing any view underneath the apple system status bar, leaving a black bar at the top, which is no good, but it shows I'm modifying the right area in the code, at least:
- (void)addLeftViewControllerToHierarchy
{
CGRect lvFrame;
if (self.leftViewController != nil && ![self.childViewControllers containsObject:self.leftViewController])
{
[self addChildViewController:self.leftViewController];
self.leftViewContainer.viewController = self.leftViewController;
if (self.leftViewContainer == nil)
{
self.leftViewContainer = [[PKRevealControllerContainerView alloc] initForController:self.leftViewController shadow:NO];
self.leftViewContainer.autoresizingMask = [self autoresizingMaskForLeftViewContainer];
}
lvFrame = [self leftViewFrame];
lvFrame.origin.y += 20; // ugly hack demo code only! don't really do it this badly!
lvFrame.size.height -= 20;
self.leftViewContainer.frame = lvFrame;
[self.view insertSubview:self.leftViewContainer belowSubview:self.frontViewContainer];
[self.leftViewController didMoveToParentViewController:self];
}
}
The above hack is almost enough, if I also add this to UIViewController+PKRevealController.m:
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleBlackOpaque;
}
The above code, when added, causes the following hint/warning:
Category is implementing a method that will also be implemented by its primary class.
I'm including the above notes to show what I've tried, and I welcome some idea of how the real experts are doing this.
My own modified copy of the PKRevealController code, including the hack above, in a slightly improved form, is found here: https://github.com/wpostma/PKRevealController
I've been struggling with PKRevealController as well. While I'm still looking for better solutions I will share what I came up with until now.
My two problems were:
Status bar style was always the same and I wanted a different style for the front view and the menu;
The menu view top cell (it's a table view controller) showed up behind the status bar.
1. Dynamic status bar style
First I had my own PKRevealController subclass where I was having a custom initialiser and some custom methods to load new view controllers into the front view navigation view controller. But that's not relevant for now.
I used this subclass to implement preferredStatusBarStyle as follows so that the reveal controller can provide the right style for each state:
- (UIStatusBarStyle)preferredStatusBarStyle {
switch (self.state) {
case PKRevealControllerFocusesLeftViewController:
return [self.leftViewController preferredStatusBarStyle];
break;
case PKRevealControllerFocusesRightViewController:
return [self.rightViewController preferredStatusBarStyle];
break;
case PKRevealControllerFocusesFrontViewController:
return [self.frontViewController preferredStatusBarStyle];
break;
case PKRevealControllerFocusesLeftViewControllerInPresentationMode:
return [self.leftViewController preferredStatusBarStyle];
break;
case PKRevealControllerFocusesRightViewControllerInPresentationMode:
return [self.rightViewController preferredStatusBarStyle];
break;
default:
return UIStatusBarStyleDefault;
break;
}
}
This alone doesn't work however. You still have to say that the status bar style needs to change with setNeedsStatusBarAppearanceUpdate. As Apple says this should be called from inside an animation loop and you can find one in PKRevealController's setFrontViewFrameLinearly method. This is how it looks after I've modified it:
- (void)setFrontViewFrameLinearly:(CGRect)frame
animated:(BOOL)animated
duration:(CGFloat)duration
options:(UIViewAnimationOptions)options
completion:(PKDefaultCompletionHandler)completion
{
[UIView animateWithDuration:duration delay:0.0f options:options animations:^
{
self.frontViewContainer.frame = frame;
if ([[[UIDevice currentDevice] systemVersion] compare:#"7.0" options:NSNumericSearch] != NSOrderedAscending) {
[self setNeedsStatusBarAppearanceUpdate];
}
}
completion:^(BOOL finished)
{
safelyExecuteCompletionBlockOnMainThread(completion, finished);
}];
}
If you try it out at this point the styles will be mixed up. You can quickly conclude that by the time preferredStatusBarStyle is called the reveal controller state is still not changed. For that go to every method that sets the state, e.g. enterPresentationModeForRightViewControllerAnimated and set the state before it calls any change to the frame (the one is going to trigger the animation loop). I did it in 5 different places.
2. Left/Right menu with inset
For this one I have to say I used a workaround: I've just set a header view on the table view (tableHeaderView property).
Put this in viewDidLoad of your UITableViewController:
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, self.tableView.frame.size.width, 20.f)];
headerView.backgroundColor = [UIColor whiteColor];
self.tableView.tableHeaderView = headerView;
Don't forget to add some condition so it doesn't get executed in iOS 6. Use this other answer to know how to do it.
If you don't need iOS 5- support, you could use autolayout and align topmost views to topLayoutGuide.
So, for example, if your left view controller is a UIViewController with a UITableView in it, you could snap UITableView's top edge to the topLayoutGuide.
You can do it in (1) IB (storyboard) or (2) from code.
I personally prefer the first approach, as far as it removes the need of unnecessary code. You just open your storyboard and snap your table view's top edge to topLayoutGuide. In iOS 7 you'll end up with topLayoutGuide constraint, in iOS6 topLayoutGuide constraint is converted to a common to-container-view constant.
If you use second approach, you'll have to make sure you don't use topLayoutGuide in iOS6, something like this:
// assume you'r in your UIViewController subclass
if (![self respondsToSelector:#selector(topLayoutGuide)])
{
// topLayoutGuide is not supported, probably iOS6
// add constraints to snap tableview's top edge to superview's top edge
}
else
{
// cool, topLayoutGuide is supported, probably iOS7
// add constraints to snap tableview's top edge to topLayoutGuide
}

Hide or temporarily remove a child ViewController from a parentViewController?

(asking and self-answering, since I found no hits on Google, but managed to find a solution in the end by trial and error)
With iOS 5 and 6, Apple added some ugly hacks to make InterfaceBuilder support "embedded" viewcontrollers. They didn't document how those work, they only give code-level examples, and they only cover a limited subset of cases.
In particular, I want to have an embedded viewcontroller that is sometimes hidden - but if you try the obvious approach it doesn't work (you get a white rectangle left behind):
childViewController.view.hidden = TRUE;
Why don't you just create an IBOutlet to your container view and do
self.containerView.hidden = YES;
How they've done it appears to be a variation on the manual way that worked since iOS 2 (but which only supported views, not viewcontrollers) - there is a real, genuine UIView embedded into the parent (not mentioned in the source code examples - it's only added when you use InterfaceBuilder!).
So, instead, if you do:
childViewController.view.superview.hidden = TRUE;
...it works!
Also, counterintuitively, you can call this method at any time from viewDidLoad onwards - the "embed segue" hack from Apple is executed before viewDidLoad is called.
So you can do this on startup to have your childViewController start off invisible.
Use This [self.childviewController setHidden:YES];
In case somebody will need to hide/show all child views or iterate over them:
func hideChildrenViews() {
for view in self.view.subviews {
(view as! UIView).hidden = true
}
}
func showChildViews() {
for view in self.view.subviews {
(view as! UIView).hidden = false
}
}

Using UIAppearance and switching themes

I'm looking to theme my iOS app and have been reading up on UIAppearance. I want the user to be able to switch between a number of different visual themes from within the app. Changing a theme would then be shown in the UI.
I'm thinking I could have a theme file that is a singleton loaded within the appDelegate.m. But after that i'm a little stuck on how this could be implemented?
UIKit sets properties from UIAppearance proxy after view is added to views hierarchy.
In UISS I use method like this:
- (void)reloadAppearance {
NSArray * windows = [UIApplication sharedApplication].windows;
for (UIWindow *window in windows) {
for (UIView *view in window.subviews) {
[view removeFromSuperview];
[window addSubview:view];
}
}
}
Another trick is to remove rootViewController from main window and add it again. Though I prefer the first solution, because it covers wider range of cases.
This works for me in Swift:
let windows = UIApplication.sharedApplication().windows
for window in windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
}
The solution suggested by Robert, doesn't work for me . I'm using iOS9 and UITabbarController .
This suggestion is the only that worked from answer here
It basically explained the problem well, when we use UIAppearance, it basically is applied and will not change until the views is redrawn again which will not happen especially with rootViewController like UITabbarControllers and new colors will only have effect ONLY AFTER the App is removed from memory and opened again, if you want an immediate change , you will have to make it by hand and setting each property like described in the answer in attached link
swift 4:
let windows = UIApplication.shared.windows
for window in windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
}

Make custom keyboard non-movable

We created a custom numeric keypad for iPad. On our testers iPad this keyboard was suddenly moved out of place and it took us quite a while to figure out that it is possible to move that custom keyboard by start dragging at the location where the "Keyboard Button" would normally be located.
The customers will have very hard times to move it back in case they accidentally moved it. As it makes no sense to move the keyboard on that specific input screen I would rather prefer to prevent the keyboard from moving instead of painting some kind of handle that makes visible to the users that the keyboard can be moved. (This is a special input screen for just editing one single numeric value. The keyboard is like part of the layout and is always visible on this screen.)
I tried hard but could not find a way to prevent the keyboard from moving when dragged on this specific place. Even all my dirty ideas like removing possibly preexisting GestureRecognizers (there were none) or placing my own button in front did not help.
Edit:
The keyboard is even movable in the simplest possible custom keyboard app written in Monotouch I can think of. Did I missed something?
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace KeyboardTest
{
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
private UIWindow window;
private UIViewController viewController;
private UIViewController keyboardViewController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
// Create a red dummy keyboard
keyboardViewController = new UIViewController();
keyboardViewController.View.BackgroundColor = UIColor.Red;
// Create a textfield and assign our beautiful red keyboard as its InputView
UITextField textField = new UITextField();
textField.BorderStyle = UITextBorderStyle.RoundedRect;
textField.Frame = new System.Drawing.RectangleF(44, 44, 200, 44);
textField.InputView = keyboardViewController.View;
// create a rootview controller and add our textfield
viewController = new UIViewController();
viewController.View.AddSubview(textField);
window.RootViewController = viewController;
window.MakeKeyAndVisible ();
return true;
}
}
}
For what you explain, I´m guessing that you have your keyboard as a subview of your main view. Instead, I would set it as a inputView of the UItextFields and then make the first of your textFields be the firs responder on viewDidLoad. Something like:
-(void)viewDidLoad{
[super viewDidLoad];
CustomkeyPad *keypad=[[CustomKeyPad alloc]init]; // initWithFrame would probably be better
self.textField.delegate=self;
self.textField.inputView=keypad;
[self.textField becomeFirstResponder];
}
I´m not in my Mac so I made probably some mistake here, but that´s the idea and That´s how I did it when I did my custom keypad as well and it´s universal (iPad and iPhone) for both landscape and portrait modes and so far it has given me no problems.

Resources