Page view controller using CAPSPageMenu controller titles are not displaying according to Screen size in iOS 10? - uiviewcontroller

I am using CAPSPageMenu for page controller, loading two view controllers as a first screen, but it is not displaying controller title array in 6s plus device. it is displaying like this,
I want to display half the screen as for screen size.
Here is my code i am using ,
NSArray *controllerArray = #[jobVC, course];
NSDictionary *parameters = #{CAPSPageMenuOptionMenuItemSeparatorWidth: #(1.0),
CAPSPageMenuOptionUseMenuLikeSegmentedControl: #(YES),
CAPSPageMenuOptionMenuMargin:#(20.0),
CAPSPageMenuOptionMenuItemSeparatorRoundEdges: #(YES),
CAPSPageMenuOptionSelectionIndicatorHeight :#(2.0),CAPSPageMenuOptionMenuItemSeparatorPercentageHeight: #(0.5)
};
_pageMenu = [[CAPSPageMenu alloc] initWithViewControllers:controllerArray frame:CGRectMake(0.0, 0.0, self.contentView.frame.size.width, self.contentView.frame.size.height) options:parameters];
_pageMenu.delegate = self;
[self.contentView addSubview:_pageMenu.view];

You should set your view contollers correctly. Like this way:
Firstly add a property for CAPSPageMenu in your base view controller:
#property (nonatomic) CAPSPageMenu *pagemenu;
Then add following code in the viewDidLoad function in your view controller:
NSMutableArray *controllerArray = [NSMutableArray array];
// Example view controller creation:
UIViewController *firstController = [UIViewController alloc] initWithNibname:#"YourFirstControllerNibName" bundle:nil];
controller.title = #"YOUR SAMPLE TITLE (eg. SEARCH JOBS)";
[controllerArray addObject:firstControllerName ];
UIViewController *secondController = [UIViewController alloc] initWithNibname:#"YourSecondControllerNibName" bundle:nil];
secondController .title = #"YOUR SAMPLE TITLE (eg. SEARCH COURSE)";
[controllerArray addObject:secondController ];
//Customize your page menu with parameters:
NSDictionary *parameters = #{CAPSPageMenuOptionMenuItemSeparatorWidth: #(1.0),
CAPSPageMenuOptionUseMenuLikeSegmentedControl: #(YES),
//... and more...
};
// Initialize page menu
_pageMenu = [[CAPSPageMenu alloc] initWithViewControllers:controllerArray frame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height) options:parameters];
//Optional delegate
_pageMenu.delegate = self;
// Lastly add page menu as subview of base view controller view
[self.view addSubview:_pageMenu.view];
You can also use these delegate functions below for control move actions if you want:
- (void)willMoveToPage:(UIViewController *)controller index:(NSInteger)index {}
- (void)didMoveToPage:(UIViewController *)controller index:(NSInteger)index {}

Related

UIViewController lifecycle broken iOS13, makeKeyAndVisible() seems not to operate?

I have a custom UIStoryboardSegue that works as desired in iOS12.*.
One of the destination view controller is a UITabbarController: for each tab, I have a controller embedded in a navigation controller.
Unfortunately, for iOS13.*, this does not work well: the view controller lifecycle is broken, and no call the viewXXXAppear() nor the willTransition() methods are no longer issued.
It looks like makeKeyAndVisible() has no effect?!
See at the bottom how the screen UI is puzzled below without viewWillAppear() being called.
An horrible temporary workaround
I had to pull my hairs but, I have found a fix which I make public (I had to add a navigation controller on the fly).
This messes the vc hierarchy: do you have a better solution?
public class AladdinReplaceRootViewControllerSegue: UIStoryboardSegue {
override public func perform() {
guard let window = UIApplication.shared.delegate?.window as? UIWindow,
let sourceView = source.view,
let destinationView = destination.view else {
super.perform()
return
}
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
destinationView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
window.insertSubview(destinationView, aboveSubview: sourceView)
// **My fix**
if #available(iOS 13,*) {
// I introduced an invisible navigation controller starting in iOS13 otherwise, my controller attached to the tabbar thru a navigation, dont work correctly, no viewXAppearis called.
let navigationController = UINavigationController.init(rootViewController: self.destination)
navigationController.isNavigationBarHidden = true
window.rootViewController = navigationController
}
else {
window.rootViewController = self.destination
}
window.makeKeyAndVisible()
}
}
I found a solution thanks to Unbalanced calls to begin/end appearance transitions with custom segue
What happens here is that the creation and attaching of the destination view controller happens twice, and the first one happens too soon.
So what you need to do is:
public class AladdinReplaceRootViewControllerSegue: UIStoryboardSegue {
override public func perform() {
guard let window = UIApplication.shared.delegate?.window as? UIWindow,
let sourceView = source.view,
let destinationView = destination.view else {
super.perform()
return
}
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
let mock = createMockView(view: desination.view)
window.insertSubview(mock, aboveSubview: sourceView)
//DO SOME ANIMATION HERE< MIGHT NEED TO DO mock.alpha = 0
//after the animation is done:
window.rootViewController = self.destination
mock.removeFromSuperview()
}
func createMockView(view: UIView) -> UIImageView {
UIGraphicsBeginImageContextWithOptions(view.frame.size, true, UIScreen.main.scale)
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return UIImageView(image: image)
}
}
I had a similar problem on iOS 13 when performing a custom storyboard segue that replaces the rootViewController. The original code looked like this:
#interface CustomSegue : UIStoryboardSegue
#end
#implementation CustomSegue
- (void)perform {
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
UIViewController *destination = (UIViewController *) self.destinationViewController;
[destination.view removeFromSuperview];
[appDelegate.window addSubview:destination.view];
appDelegate.window.rootViewController = destination;
}
#end
Removing the line [appDelegate.window addSubview:destination]; fixed the problem to me. Apparanently, it was unnecessary to add the new VC's view as a subview to the window. It did the job correctly even after removing that line, and it also fixed the error message "unbalanced calls to begin/end appearance transitions".

Keyboard is not enabling after navigation takes place in ios

While I am navigating to the particular controller I want keyboard to enable after the navigation takes place. In IndexPageTableViewController it has a textField named searchField I need to enable the keyboard.
-(void) navigateToSearch
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone"
bundle: nil];
if(mainStoryboard)
{
IndexPageTableViewController *index = (IndexPageTableViewController *) [mainStoryboard instantiateViewControllerWithIdentifier:#"IndexPageTableViewController"];
[[SlideNavigationController sharedInstance ] popToRootAndSwitchToViewController:index withSlideOutAnimation:NO andCompletion:^{
[self initTableView];
[self becomeFirstResponder];
}];
}
}

iOS UIViewController pushViewController issue

I've subclass UINavigationController like this:
#implementation BaseNavigationController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1];
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.viewControllers.count) {
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
And also I've a subclass of UIViewController like this:
#implementation BaseViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tabBarController.tabBar.translucent = NO;
self.navigationController.navigationBar.translucent = NO;
self.view.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
All my view controller are inheriting the baseViewController and all my navigation controller are inheriting the baseNavigationController.
UITabBarViewController -> BaseNavigationController -> BaseViewController
The issue is sometimes when my application is back from background and tap a cell (UITableView or UICollectionView), pushViewController do not work, and the app get stuck.Or sometimes only navigation bar pushed to next view controller,shows next view controller's title and the app also get stuck.The next view controller's viewDidLoad method is called.
I've worried for a week and I do not know why this is happened,so please help me to fix this odd issue.
Not 100% get this issue ,only sometimes.Thank you.

iOS 8: Presenting a modal view controller in portrait causes resize of the navigation bar of the underlying landscape navigation controller

On iOS 8 I have a strange behavior regarding the navigation bar and orientation changes.
I have a navigation controller which reports a supported interface orientation UIInterfaceOrientationMaskLandscapeRight. The navigation bar has the expected height for landscape orientation (sadly I am not entitled to post screenshots).
Then I initiate a modal presentation of a view controller that only supports UIInterfaceOrientationMaskPortrait. When the presentation animation starts, it seems that the metrics of the underlying navigation controller are changed to a portrait presentation, as the height of the navigation bar grows to its portrait size, as depicted above.
iOS 7 does not exhibit this behavior. What am I missing? I want to restore the old behavior.
Here is the full code of the simple example above:
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
DOGButtonViewController *root = [DOGButtonViewController new];
DOGOrientedNavigationController *navi = [[DOGOrientedNavigationController alloc] initWithRootViewController:root];
navi.allowedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
self.window.rootViewController = navi;
[self.window makeKeyAndVisible];
return YES;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait;
}
#end
#implementation DOGOrientedNavigationController
- (NSUInteger)supportedInterfaceOrientations
{
return self.allowedInterfaceOrientations;
}
#end
#implementation DOGButtonViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Button View Controller";
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (IBAction)buttonClicked:(id)sender
{
DOGPortraitViewController *vc = [DOGPortraitViewController new];
[self presentViewController:vc animated:YES completion:nil];
}
#end
#implementation DOGPortraitViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Portrait Title";
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (IBAction)buttonClicked:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
#end
In a more complex setup I also experience the text in a UIWebView contained in the navigation controller being scaled up when presenting the portrait modal. When dismissing the modal, the text is not resized to its original size.
For lack of a better option I've done a bit of a hack for this.
Basically before I show the modal view I take a screen shot and lay it on top of the presenting view controller.
Obviously I have to remove this screen shot when the view re-appears
func showScreenShot () {
let image = screenShot()
self.screenShotImageView = UIImageView(image: image)
self.view.addSubview(self.screenShotImageView!)
}
func screenShot () -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, true, UIScreen.mainScreen().scale)
self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image
}
func removeScreenShot () {
if let screenImageView = self.screenShotImageView {
screenImageView.removeFromSuperview()
self.screenShotImageView = nil
}
}

Cannot load the Google Maps view in iOS

I'm trying to load google maps view in iOS following the guide here
I created a new viewController for the map view called iptechMapViewController.h , iptechMapViewController.m and iptechMapViewController.xib
Here is the code in iptechMapViewController.m :
#import "iptechMapViewController.h"
#import <GoogleMaps/GoogleMaps.h>
#interface iptechMapViewController ()
{
GMSMapView *mapView_;
}
#end
#implementation iptechMapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683
longitude:151.2086
zoom:6];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.myLocationEnabled = YES;
self.view = mapView_;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(-33.8683, 151.2086);
marker.title = #"Sydney";
marker.snippet = #"Australia";
marker.map = mapView_;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Then in another view controller named iptechFlipsideViewController.m I'm trying to show the iptechMapViewController as follows:
- (IBAction)showMap:(id)sender
{
iptechMapViewController *controller = [[iptechMapViewController alloc] initWithNibName:#"iptechMapViewController" bundle:nil];
[self.view addSubview:controller.view];
}
But after clicking the showMap button which is connected to the IBAction showMap, and after iOS asks permission to access my location alert appears and I touch OK, after that nothing shows up and in the console I get the following error"
Failed to make complete framebuffer object 8cd6
Thanks
Passing CGRectZero to mapWithFrame only works if the map view is the root view controller's root view - in which case it is resized to fit the screen. In your case since the map is a subview, you will need to specify a size when creating the map view.