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

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.

Related

Why does subclassing the main ViewController's view causes delegates to never fire?

I made a customView that implements its own delegate and set it up inside the main viewController. It works perfectly well, it's the standard practice, there's no need to show any code.
For the sake of better organizing the code I created a manager called customManager that contains the customView and the main viewController's view.
Instead of having all the code that it's needed inside the viewController (managing how the customView is setup and also listening to its delegate) I moved all that code to the customManager instead. That's why I made the customManager just to clear up the code that's inside the viewController.
All renders properly but the delegate never fires.
CustomManager.h
#import "CustomView.h"
#interface CustomManager : NSObject <CustomViewDelegate>
#property (weak) UIView *view; // viewController's view
#property (strong) CustomView *customView;
- (void)load;
#end
CustomManager.m
#import "CustomManager.h"
#implementation CustomManager
// Initialization Method
- (void)load {
_customView = [[CustomView alloc] init];
_customView.delegate = self; // !!!
_customView.frame = CGRectMake(0.0, 20.0, _view.frame.size.width, _view.frame.size.height - 20.0);
[_view addSubview:_customView];
}
#pragma mark - CustomViewDelegate
// Delegate Methods
#end
ViewController.h
#import "CustomManager.h"
#interface ViewController : UIViewController
#property (strong) CustomManager *customManager;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_customManager = [[CustomManager alloc] init];
_customManager.view = self.view;
[_customManager load];
// 1. The load method above removes the code needed here for initializing the customView and setting it up correctly.
// 2. The delegate methods are now in the customManager and leave the space below clear.
}
#end

How to get viewForZoomingInScrollView to work across multiple UIViewControllers in Xcode?

I'm relatively new to Xcode, and am in the process of making an app in Objective C with several viewControllers each with a single UIScrollView containing a single UIImage that can be zoomed and scrolled.
This code works for the first image (dermatomes), but I can't figure out how to tweak the UIView to enable zooming and scrolling on the second image (anatomicPlanes). Currently the second image imports correctly to the second UIScrollView, but when I try to zoom it just jumps down and right and remains static there.
The size of the UIScrollViews were set using Interface Builder, no problems there.
viewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *dermatomeScrollView;
UIImageView *dermatomesImageView;
IBOutlet UIScrollView *anatomicPlaneScrollView;
UIImageView *anatomicPlanesImageView;
}
#property (strong, nonatomic) IBOutlet UIScrollView *dermatomeScrollView;
#property (strong, nonatomic) IBOutlet UIImageView *dermatomesImageView;
#property (strong, nonatomic) IBOutlet UIImageView *anatomicPlanesImageView;
#property (strong, nonatomic) IBOutlet UIScrollView *anatomicPlaneScrollView;
#end
viewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize dermatomeScrollView, anatomicPlanesImageView, dermatomesImageView, anatomicPlaneScrollView;
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return dermatomesImageView;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *dermatomes = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"dermatomes.jpg"]];
self.dermatomesImageView = dermatomes;
dermatomeScrollView. maximumZoomScale = 1.2;
dermatomeScrollView. minimumZoomScale = 0.4;
dermatomeScrollView. delegate = self;
[dermatomeScrollView addSubview:dermatomesImageView];
dermatomeScrollView.zoomScale = 0.6;
UIImageView *planes = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"anatomic planes.jpg"]];
self.anatomicPlanesImageView = planes;
anatomicPlaneScrollView. maximumZoomScale = 1.2;
anatomicPlaneScrollView. minimumZoomScale = 0.4;
anatomicPlaneScrollView. delegate = self;
[anatomicPlaneScrollView addSubview:anatomicPlanesImageView];
anatomicPlaneScrollView.zoomScale = 0.6;
}
Any help is appreciated!
You need to return the correct view based on the scroll view that is requesting. Every method in the delegate pattern is passed a reference to the originator of the method call, so your delegate implementation can handle it differently. In this case, the originator of the delegate method call is the scroll view:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
if (scrollView == dermatomeScrollView) {
return dermatomesImageView;
}
return anatomicPlanesImageView;
}
If you add more scrollviews, you'll have to extend this method further.

'Casting' a UIView defined in Storyboard to a subclass

This might be a really bad question, so I apologize in advance. Feel free to tell me if there is a better way to approach this.
I'm using storyboards to layout the initial arrangement of objects. Say that I put a UIView on the storyboard, and I link that view to a property in my ViewController.m file called storyboardView. At runtime, a lot might happen to that UIView, and following the MVC pattern, I'd like the code that governs that behavior to exist in a separate subclass. How can I 'cast' that UIView so that it is now responds to the subclass rather than the ViewController?
I'm thinking of something along these lines, but this doesn't work. It doesn't throw any errors, but the background color isn't turning red, so I know that I am unsuccessful:
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIView *storyboardView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.storyboardView = [[MyView alloc] initWithFrame:self.storyboardView.frame];
}
#end
Subclass Header:
#import <UIKit/UIKit.h>
#interface MyView : UIView
#end
Subclass Implementation:
import "MyView.h"
#implementation MyView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor redColor];
}
return self;
}
#end
In storyboard you can change the UIView to any subclass like this

Changing MasterViewController width in UISplitViewController iOS 8 iPhone not working

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.

Variable not passed to UIView

I am trying to pass a variable from within my main UIViewController to a UIView.
CGRect frame = CGRectMake(0,0,347, 308);
XBMCPopUpView * xbmcpop = [[XBMCPopUpView alloc]initWithFrame:frame];
xbmcpop.DevIP = #"2222";
[self.view addSubview:xbmcpop];
the Object xbmcpop gets created and its string property "DevIP" gets assigned correctly. But when the UIVIEW is actually viewed it seems like the instance that is viewed is different from the one I created and the variable #"2222" is not passed to the string property "DevIP"
Note: My Main UIViewController is in a storyboard with a navigation controller
If you are interested to see the "XBMCPopUpView class, here it is:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#class XBMCPopUpView;
#interface XBMCPopUpView : UIView
{
NSString * DevIP;
}
#property (strong,nonatomic) NSString *DevIP;
- (id)initWithFrame:(CGRect)frame;
-(IBAction)sendPlay:(id)sender;
#end
Under
#interface XBMCPopUpView : UIView
remove
{
NSString * DevIP;
}
Since you're using a storyboard, you need to use your view controller's awakeFromNib method for this.
When you add the awakeFromNib method, don't forget to call [super awakeFromNib] there.
- (void)awakeFromNib
{
[super awakeFromNib];
CGRect frame = CGRectMake(0,0,347, 308);
XBMCPopUpView * xbmcpop = [[XBMCPopUpView alloc]initWithFrame:frame];
xbmcpop.DevIP = #"2222";
[self.view addSubview:xbmcpop];
}

Resources