Changing MasterViewController width in UISplitViewController iOS 8 iPhone not working - ios

So I am trying to build an iPhone app that uses a SplitView for the main screen Similar to the app Lyft or like basically this controller https://github.com/mutualmobile/MMDrawerController.
I have set up the following storyboard (I am not using SizeClasses) :
I have subclassed the SplitViewController to try to set a max width for my MasterViewController:
// File .h
#import <UIKit/UIKit.h>
#interface LLSplitViewController : UISplitViewController <UISplitViewControllerDelegate>
#property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);
#end
// File .m
#implementation LLSplitViewController
-(void)viewDidLoad{
self.delegate = self;
self.preferredPrimaryColumnWidthFraction = .1;
CGRect mainScreen = [[UIScreen mainScreen] bounds];
self.maximumPrimaryColumnWidth = mainScreen.size.width - 100;
}
#end
What am I missing here?

I ended up using this framework to achieve my goal.
It is not a splitcontroller but it works similar to it and it seems to be very well maintained.

Related

How to create an App using the Single View App template where the main window does not rotate but the rest does?

How to create an App using the Single View App template where the main window does not rotate but its rootViewController and everything else autorotates?
Apple does that on CIFunHouse but because the code is poorly explained in that matter, it is impossible to know how they did it. If you run the app you will see that the camera's preview window does not autorotate because the preview was added to the window but everything else does.
Apple uses this technique on their native iPad camera app.
So the answer is not clean but I can give you a fix. At some point the main application window must not have autorotated like it does now but at some point it started rotating according to the rootviewcontroller. At least this source code suggests that. I started developing at the end of iOS 6 and I think this source was written about that time. The best fix I could find for allowing everything to rotate in the example for me but having the preview to not rotate was to add a second window. Set the main window background to clear. Then add the previewLayer to the second window behind the main window. In code it would look like this.
The AppDelegate looked like this.
#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
#interface FHAppDelegate : UIResponder <UIApplicationDelegate>
{
#private
CMMotionManager *_motionManager;
}
#property (strong, readonly, nonatomic) CMMotionManager *motionManager;
//future preview window
#property (strong, nonatomic) UIWindow *previewWindow;
#property (assign, readonly, nonatomic) UIDeviceOrientation realDeviceOrientation;
#end
Then in the viewDidLoad of the FHViewController instead of adding to the main window I did this and it added where they get the main window I add the previewView to that.
// we make our video preview view a subview of the window, and send it to the back; this makes FHViewController's view (and its UI elements) on top of the video preview, and also makes video preview unaffected by device rotation
//nothing special about this viewcontorller except it has
//-(BOOL)shouldAutorotate{
//return NO;
//}
TestViewController *test = [[TestViewController alloc]initWithNibName:#"TestViewController" bundle:nil];
FHAppDelegate *delegate = ((FHAppDelegate *)[UIApplication sharedApplication].delegate);
delegate.previewWindow = [[UIWindow alloc]initWithFrame:window.bounds];
UIWindow *previewWindow = delegate.previewWindow;
[window setBackgroundColor:[UIColor clearColor]];
previewWindow.rootViewController = test;
previewWindow.windowLevel = UIWindowLevelNormal - 1;
[previewWindow setBounds:delegate.window.bounds];
[previewWindow makeKeyAndVisible];
[previewWindow addSubview:_videoPreviewView];
[previewWindow sendSubviewToBack:_videoPreviewView];
Because the previewWindow has to have a rootviewcontroller and it determines the rotation you can see my testviewcontroller has autorotate of NO. Hope this helps. It is working for me on iOS 10.
Edit: The view in the example above does not rotate but the window animation on rotation is bad visually. It can be removed by overriding
willTransitionToSize
[UIView setAnimationsEnabled:NO];
and after completion
[UIView setAnimationsEnabled:YES];
See swift version on GitHub
For an iPad requires Full Screen must be check.
With using navigation controller you can create an Objective-C category like and use these in sub viewcontrollers
#import "UINavigationController+Orientation.h"
#implementation UINavigationController (Orientation)
- (NSUInteger)supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate {
return YES;
}
#end
For Swift
extension UINavigationController {
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return topViewController?.supportedInterfaceOrientations ?? .portrait
}
open override var shouldAutorotate: Bool {
return true
}
}

Howto achieve animation like store house in ios?

Hi all i have got to implement storehouse like animation in my project. I found a third party library but sorry it is in swift. Please help me with objective c code
Refference link for animation is
Animation Store house
StoreTableView.h
#import <UIKit/UIKit.h>
#protocol StoreHouseTableViewTransform
#property (nonatomic) CGFloat scaleValue;
-(void)transFormForCell:(CGFloat)scaleFactor;
#end
#interface StoreTableView : UITableView
#end
StoreTableView.m
#import "StoreTableView.h"
#implementation StoreTableView
-(void)layoutSubviews{
[super layoutSubviews];
[self transformTable];
}
- (void )transformTable{
for (NSIndexPath *indexpath in self.indexPathsForVisibleRows) {
UITableViewCell *cell = [self cellForRowAtIndexPath:indexpath];
if ([cell conformsToProtocol:#protocol(StoreHouseTableViewTransform)]) {
UITableViewCell <StoreHouseTableViewTransform> *vc = (UITableViewCell<StoreHouseTableViewTransform> *)cell;
CGFloat distCenter=[self computeDistance:indexpath];
[vc transFormForCell:[self computeScale:distCenter withMinScale:vc.scaleValue]];
}
}
}
-(CGFloat )computeDistance:(NSIndexPath *)indexpath{
CGRect rect=[self rectForRowAtIndexPath:indexpath];
CGFloat cellCenter=rect.origin.y + rect.size.height/2;
CGFloat cellContentCenter=self.contentOffset.y + self.bounds.size.height/2;
return fabs(cellCenter - cellContentCenter);
}
-(CGFloat )computeScale:(CGFloat)distanceOfCenter withMinScale:(CGFloat)scaleFactor{
return (1.0-scaleFactor) * distanceOfCenter / self.bounds.size.height;
}
#end
StoreTableViewCell.h
#import <UIKit/UIKit.h>
#import "StoreTableView.h"
#interface StoreTableViewCell : UITableViewCell<StoreHouseTableViewTransform>{
CGFloat minimumScale;
}
#property (weak, nonatomic) IBOutlet UIView *backView;
#property (weak, nonatomic) IBOutlet UIImageView *scaleImage;
#end
StoreTableViewCell.m
#import "StoreTableViewCell.h"
#implementation StoreTableViewCell
#synthesize scaleValue;
-(void )prepareForReuse{
[super prepareForReuse ];
minimumScale = 0.85;
self.backView.transform = CGAffineTransformMakeScale(minimumScale, minimumScale);
}
#pragma mark delegate
-(void)transFormForCell:(CGFloat)scaleFactor{
self.backView.transform = CGAffineTransformMakeScale(1.0 - scaleFactor, 1.0 - scaleFactor);
}
#end
This is objective-C implementation of StoreHouse Animation
Subclass your TableView with StoreTableView and Cell with StoreTableViewCell.
I think so this will help you
play with scaleFactor
I spent about 4 hours trying to enable Swift in my Xcode Objc-based project. My "myproject-Swift.h" file was created successfully, but my Xcode didn't see my Swift-classes. So I decided to create a new Xcode Objc-based project and finally I found the right answer! Hope this post will help someone :-)
Step by step swift integration for Xcode Objc-based project:
1.Create new *.swift file (in Xcode) or add it by using Finder
2.Add swift bridging empty header if Xcode have not done this before (see 4 below)
3.Implement your Swift class by using #objc attribute:
import UIKit
#objc class Hello : NSObject {
func sayHello () {
println("Hi there!")
}
}
4.Open Build Settings and check this parameters:
Product Module Name : myproject
Defines Module : YES
Embedded Content Contains Swift : YES
Install Objective-C Compatibility Header : YES
Objective-C Bridging Header : $(SRCROOT)/Sources/SwiftBridging.h
5. Import header (which is auto generated by Xcode) in your *.m file
#import "myproject-Swift.h"
6. Clean and rebuild your Xcode project
Profit
They have open sourced their animation engine. Built on top of CADisplayLink, they recommend this mainly if you're looking to do physics based animations that interact with gestures.
https://github.com/storehouse/Advance

confusion on UIView, its class and UIViewController - xcode iOS objective-c

In storyboard, I dragged out UIView onto my ViewController.
Assign UIView to custom class "myUIView" (which will be myUIView.h and myUIView.m)
Set up ViewController like this:
ViewController.h
#import <UIKit/UIKit.h>
#interface ScheduleViewingVC : UIViewController
//for the dragged-out UIView
#property (strong, nonatomic) IBOutlet UIView *myUIViewOutlet;
//to do some drawings on myUIViewOutlet
#property (strong, nonatomic) myUIView *myUIViewClass;
#end
ViewController.m
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//resize my UIView into a square
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGRect squareFrame = CGRectMake(0, 0, screenWidth, screenWidth);
_myUIViewOutlet = [[UIView alloc] initWithFrame:squareFrame];
}
#end
If I run this project,
- (void)drawRect:(CGRect)rect {}
inside myUIViewClass.m runs automatically since.. it's linked to myUIViewOutlet.
Now, I need send some data to myUIViewClass linked to myUIViewOutlet from ViewController.
It doesn't seem right to send data to myUIViewOutlet from ViewController..
How can I make this work correctly? Should I send data to myUIViewClass?
Can anyone make this clear for me? Thank you!
Sending data to myUIViewClass will not be right. Instead you can implement some Protocol (Delegate, DataSource kind) of mechanism.
What you can do is as follows:
Define some Custom Protocol say myUIViewProtocol in your myUIView class.
Define a delegate and methods you need.
Let your ViewController conform to this protocol and override this methods.
This approach is same as
UITableView.
Hope this helps.

Grabbing iPhone screenWidth and Height for reusability

I created a category like so:
#import "UIViewController+Dimensions.h"
#implementation UIView (Dimensions)
- (double) screenWidth2
{
return self.frame.size.width;
}
- (double) screenHeight2
{
return self.frame.size.height;
}
#end
But when I try to call it in my view controller after importing it, I get:
"Use of undeclared identifier screenWidth2;
Is there a better way to grab the screenWidth in one place then every view controller I'm in?
I then did this in my view controller:
_registerButton.frame = CGRectMake(0.0, 0.0, [self screenWidth2] / 2.0 - 1.0, 60.0);
but the app compiles runs and crashes. And the category's .h file is:
#import <UIKit/UIKit.h>
#interface UIViewController (Dimensions)
- (double) screenWidth2;
- (double) screenHeight2;
#end
You need to add
#import "UIViewController+Dimensions.h"
In the code using the category (the file where you call [uiViewControllerInstance screenWidth2])
Have you checked that those variables are declared in the .h? So, they are public.
Also, to use the category, add this:
#import "UIViewController+Dimensions.h"
In the class that have to use the category.

A few IBOutlets pointing to nil

After a long while I've finally started working with Objective-C again, on my only complete app so far. The goal is to eventually refactor for ARC and possibly storyboards, but for the time being I'm polishing the iOS 4.x target. I am quite rusty, so bar with me if this is a stupid question.
I have a button in my main view that triggers the showAction method. The method is as follows:
- (void)showAbout
{
AboutViewController *aboutView = [[[AboutViewController alloc] init] autorelease];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
aboutView.modalPresentationStyle = UIModalPresentationFormSheet;
}
else
{
aboutView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
}
[self presentModalViewController:aboutView animated:YES];
}
The AboutViewController class has this .h:
#interface AboutViewController : UIViewController <UIActionSheetDelegate, MFMailComposeViewControllerDelegate> {
}
- (IBAction)dismiss:(UIButton *)sender;
- (IBAction)feedback:(UIButton *)sender;
#property (retain) IBOutlet UIButton *dismissButton;
#property (retain) IBOutlet UIButton *feedbackButton;
#property (retain) IBOutlet UIImageView *background;
#property (retain) IBOutlet UITextView *textView;
#end
and everything has been connected properly in the .xib file (the same one for iPhone and iPad). The actions are triggered as expected, and the outlets are accessible, but only on iPhone. When running on iPad, only textView is properly initialized, and all the rest points to nil.
In the .m I have tried this:
#implementation AboutViewController
#synthesize dismissButton = _dismissButton;
#synthesize feedbackButton = _feedbackButton;
#synthesize background = _background;
#synthesize textView = _textView;
// ...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"obj self.dismiss: %#", self.dismissButton);
NSLog(#"frame dismiss: %#", NSStringFromCGRect(self.dismissButton.frame));
}
On iPhone I get this:
2012-02-08 22:51:00.341 myapp[17290:207] obj self.dismiss: <UIButton: 0x70281d0; frame = (180 410; 120 30); opaque = NO; autoresize = LM+W+RM+TM; layer = <CALayer: 0x7028260>>
2012-02-08 22:51:00.342 myapp[17290:207] frame dismiss: {{180, 410}, {120, 30}}
On iPad, instead, I get this:
2012-02-08 22:51:40.428 myapp[17320:207] obj self.dismiss: (null)
2012-02-08 22:51:40.428 myapp[17320:207] frame dismiss: {{0, 0}, {0, 0}}
There is nothing else that happens depending on the UI Idiom, and I'm really confused about this. It's as if on the iPad the outlets for anything other than textView are not set, even though they are correctly linked up in the .xib file. In viewWillAppear, self.textView is working as expected also on iPad. I also tried doing this in viewDidLoad, which should be called before viewWillAppear if I'm not mistaken, and even in the dismiss: method, but they are just never available.
The reason I need to access the buttons' frames is that the about view is relatively complex and fails to reposition its subviews automatically. The only thing I need to do is make the buttons wider on the larger modal view on iPad.
Any hints would be greatly appreciated!
Thanks in advance.
Did you ever have a separate .xibs for iPad and iPhone? If so you might have the same issue I had. That is until #AliSoftware dropped some knowledge on me:
UIView in nib is nil on iPad, and not nil on iPhone
Essentially you need to:
Delete the Build Products Directory
Delete your app from all your simulators
Build and Run
I believe the problem is that a ghost .xib for iPad was hanging around causing issues. Truly wiping the apps clean did the trick. Good luck!

Resources