I have an app that asks the user for information then their signature. Upon clicking the "sign" button they are taken to a view controller called "myviewcontroller".
From there what I want to show is the following screen, however whenever I click the "sign" button the signature capture takes the entire screen, and while it works I am unable to see the "x" where they should sign.
I don't know what I am missing, or what I've incorrectly called that's causing this to happen.
#import "MyViewController.h"
#interface MyViewController ()
#end
#implementation MyViewController
#synthesize mySignatureImage;
#synthesize lastContactPoint1, lastContactPoint2, currentPoint;
#synthesize imageFrame;
#synthesize fingerMoved;
#synthesize navbarHeight;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//set the title of the navigation view
[self.navigationItem setTitle:#"Sign here"];
//create a save button in the navigation bar
UIBarButtonItem *myButton = [[UIBarButtonItem alloc]
initWithTitle:#"Save"
style:UIBarButtonItemStylePlain
target:self
action:#selector(saveSignature:)];
[self.navigationItem setRightBarButtonItem:myButton];
//set the view background to light gray
self.view.backgroundColor = [UIColor lightGrayColor];
//get reference to the navigation frame to calculate navigation bar height
CGRect navigationframe = [[self.navigationController navigationBar] frame];
navbarHeight = navigationframe.size.height;
//create a frame for our signature capture based on whats remaining
imageFrame = CGRectMake(self.view.frame.origin.x+10,
self.view.frame.origin.y-5,
self.view.frame.size.width-20,
self.view.frame.size.height-navbarHeight-30);
//allocate an image view and add to the main view
mySignatureImage = [[UIImageView alloc] initWithImage:nil];
mySignatureImage.frame = imageFrame;
mySignatureImage.backgroundColor = [UIColor whiteColor];
[self.view addSubview:mySignatureImage];
}
There's more code for the actual signature capture, but this is the stuff directly related to the view controller.
http://i59.tinypic.com/f06ph2.jpg
http://i61.tinypic.com/29cqy8.jpg
Related
Hi I am adding one custom button programmatically on navigation bar and i have written all button properties in my background class and i am calling this method from my main class
And here I have used protocols for getting button touching event in my main class from background class but it's not working using protocols
my code:-
background class:-
BackGroundClass.h
#import <UIKit/UIKit.h>
#protocol buttonprotocol<NSObject>
#required
- (void) buttonTapped;
#end
#interface BackGroundClass : UIViewController
#property (nonatomic, weak) id<buttonprotocol> delegate;
#end
BackGroundClass.m
#import "BackGroundClass.h"
#interface BackGroundClass ()
#end
#implementation BackGroundClass
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)backbutton: (UINavigationItem *)navigationitem
{
UIImage* image3 = [UIImage imageNamed:#"back.png"];
CGRect frameimg = CGRectMake(15,5,25,25);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setBackgroundImage:image3 forState:UIControlStateNormal];
[someButton addTarget:self action:#selector(Back_btn:)
forControlEvents:UIControlEventTouchUpInside];
[someButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
navigationitem.leftBarButtonItem = mailbutton;
}
- (void)Back_btn :(id)sender
{
[delegate buttonTapped];
}
#end
main class:-
mainclass.h
#import <UIKit/UIKit.h>
#import "BackGroundClass.h"
#interface mainclass : UIViewController<buttonprotocol>
mainclass.m
#import "mainclass.h"
#import "BackGroundClass.h"
#interface mainclass ()
{
BackGroundClass * bg;
}
#end
#implementation mainclass
- (void)viewDidLoad {
[super viewDidLoad];
bg = [[BackGroundClass alloc]init];
[bg backbutton:self.navigationItem];
}
- (void)buttonTapped
{
NSLog(#"ok it's 2");
}
but that above button tapped a method isn't called what I did wrong?
When you are creating the object of your BackGroundClass class, then you are not setting the delegate of the class to self, thats why your delegate method is not calling, try it like this
bg = [[BackGroundClass alloc]init];
bg.delegate = self;
First of all, using Class in class names is bad practice. As for View Controllers you should use either ViewController or VC postfix for your class names.
For example, the proper names of your Objective-C classes would be: BackgroundViewController, MainViewController
Secondly, ViewController instances are used to react to user interaction with the view attached to this ViewController and provide visible changes based on Data component of MVC work.
So, there is no reason to use second, in your case BackgroundViewController (BackgroundClass).
For more info about MVC pattern, please refer this link:
Apple's MVC articles
As there is no need in external ViewController we also should remove the delegate using and place all logic inside this main View Controller.
Thirdly, as mentioned in Apple's Mobile HIG, buttons should have a height around 44px, so your back button's size of 25x25 would make most users experience hard trying to tap on it.
At last, you should receive the class with code similar to it:
MainViewController.h
#import <UIKit/UIKit.h>
#interface MainViewController : UIViewController
#end
MainViewController.m
#import "MainViewController.h"
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *icon = [UIImage imageNamed:#"back.png"];
static CGFloat defaultButtonSize = 44.; // Default button's tap area size
CGSize buttonSize = CGSizeMake(defaultButtonSize, defaultButtonSize);
// The size image should take inside the button
CGSize imageSizeInsideButton = CGSizeMake(25., 25.);
CGRect frameimg = CGRectMake(15., 5., defaultButtonSize, defaultButtonSize);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setImage:icon forState:UIControlStateNormal];
[someButton addTarget:self
// No need to put colon after method name,
// since you have no use of control that triggered action
action:#selector(backButtonClicked)
forControlEvents:UIControlEventTouchUpInside];
someButton.showsTouchWhenHighlighted = YES;
// Calculate edge insets so image will take the size
// you specified dozen of lines before
CGFloat imageVerticalPaddingInButton = (buttonSize.height - imageSizeInsideButton.height) / 2.;
CGFloat imageHorizontalPaddingInButton = (buttonSize.height - imageSizeInsideButton.height) / 2.;
// Apply it to button
someButton.imageEdgeInsets = UIEdgeInsetsMake(imageVerticalPaddingInButton,
imageHorizontalPaddingInButton,
imageVerticalPaddingInButton,
imageHorizontalPaddingInButton);
UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
self.navigationItem.leftBarButtonItem = mailbutton;
}
// As stated in "addTarget", there is no "sender" since you don't really need it
// If you ever would need the use of it,
// don't forget to put colon in "addTarget" UIButton's method
// and place something like :(UIButton *)buttonThatClicked
// after methodName
- (void)backButtonClicked {
// Get back to your previous view controller or do whatever you like there
[self.navigationController popViewControllerAnimated:YES];
}
#end
But if you want to use this thing in as many View Controllers as possible, then you should create the category:
UIViewController+CustomBackButton.h
#import <UIKit/UIKit.h>
#interface UIViewController (CustomBackButton)
- (void)setBackButtonImage:(UIImage *)image withSize:(CGSize)size target:(id)target selector:(SEL)selector;
#end
UIViewController+CustomBackButton.m
#import "UIViewController+CustomBackButton.h"
#implementation UIViewController (CustomBackButton)
- (void)setBackButtonImage:(UIImage *)image withSize:(CGSize)size target:(id)target selector:(SEL)selector {
static CGFloat defaultButtonSize = 44.;
CGSize buttonSize = CGSizeMake(defaultButtonSize, defaultButtonSize);
CGRect frameimg = CGRectMake(15., 5., defaultButtonSize, defaultButtonSize);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setImage:image forState:UIControlStateNormal];
[someButton addTarget:target
action:selector
forControlEvents:UIControlEventTouchUpInside];
someButton.showsTouchWhenHighlighted = YES;
CGFloat imageVerticalPaddingInButton = (buttonSize.height - size.height) / 2.;
CGFloat imageHorizontalPaddingInButton = (buttonSize.height - size.height) / 2.;
someButton.imageEdgeInsets = UIEdgeInsetsMake(imageVerticalPaddingInButton,
imageHorizontalPaddingInButton,
imageVerticalPaddingInButton,
imageHorizontalPaddingInButton);
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:someButton];
self.navigationItem.leftBarButtonItem = backButton;
}
#end
And then your View Controller's implementation file will be much cleaner.
MainViewController.m
#import "MainViewController.h"
#import "UIViewController+CustomBackButton.h"
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *icon = [UIImage imageNamed:#"back.png"];
CGSize iconSize = CGSizeMake(25., 25.);
[self setBackButtonImage:icon
withSize:iconSize
target:self
selector:#selector(backButtonClicked)];
}
- (void)backButtonClicked {
// Get back to your previous view controller or do whatever you like there
[self.navigationController popViewControllerAnimated:YES];
}
#end
And then you can use this on every ViewController to customize your back button.
I am trying to change self.navigationController.toolbar position to top instead of a bottom.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIToolbarDelegate, UIBarPositioningDelegate>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// View did load
- (void)viewDidLoad
{
// Superclass view did load method call
[super viewDidLoad];
// UIToolbarDelegate
self.navigationController.toolbar.delegate = self;
}
- (void)viewDidLayoutSubviews
{
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.frame = CGRectMake(self.navigationController.toolbar.frame.origin.x, 64.0f, self.navigationController.toolbar.frame.size.width, self.navigationController.toolbar.frame.size.height);
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"First", #"Second"]];
segmentedControl.frame = CGRectMake(50.0f, 10.0f, 220.0f, 24.0f);
segmentedControl.selectedSegmentIndex = 1;
[self.navigationController.toolbar addSubview:segmentedControl];
}
- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
#end
The position changes at first, but later gets back to the bottom. Please, help me!
First make sure that toolbar delegate method positionForBar: is get called. If not, then your toolbar delegate is not properly set and you've have to define the UIToolbarDelegate protocol inside your header class.
#interface ExampleViewController : UIViewController <UIToolbarDelegate>
...
#end
Then set the delegate and also change the frames for toolbar. However, for the orientation you might have to reconsider the frames of toolbar.
#implementation ExampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
// set the toolbar delegate
self.navigationController.toolbar.delegate = self;
self.navigationController.toolbarHidden = NO;
// create a toolbar child items
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"First", #"Second"]];
segmentedControl.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.with, 24.0f);
segmentedControl.selectedSegmentIndex = 1;
[self.navigationController.toolbar addSubview:segmentedControl];
// set the frames
CGRect toolbarFrame = self.navigationController.toolbar.frame;
toolbarFrame.origin.y = self.navigationController.frame.size.height;
self.navigationController.toolbar.frame = toolbarFrame;
}
// pragma mark - UIToolbarDelegate
- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
#end
In your viewDidLoad method, add:
self.navigationController.toolbar.delegate = self;
I have a view with a property that should take an NSString from my view controller and display an image. If I hard code locationImageFile with "320x213-1.png" in my view, the image displays properly, but if I try to set locationImageFile from my view controller, the image doesn't appear. I feel like I'm missing something pretty basic. Side note: I seem to be able to set the locationTitle property from my view controller without any problems.
LocationViewController.m
#import "LocationViewController.h"
#import "LocationView.h"
#implementation LocationViewController
{
LocationView *_locationView;
}
- (void)loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
_locationView = [[LocationView alloc] initWithFrame:frame];
[self setView:_locationView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_locationView.locationTitle.text = aLocation.name;
_locationView.locationImageFile = #"320x213-1.png";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
LocationView.m
#import "LocationView.h"
#implementation LocationView
#synthesize locationTitle;
#synthesize locationImageFile;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setBackgroundColor: [UIColor blueColor]];
// Image container
UIImage *locationImage = [UIImage imageNamed:locationImageFile];
UIImageView *locationImageContainer = [[UIImageView alloc] initWithImage:locationImage];
[locationImageContainer setTranslatesAutoresizingMaskIntoConstraints:NO];
locationImageContainer.backgroundColor = [UIColor yellowColor];
[self addSubview:locationImageContainer];
// Text line
locationTitle = [[UILabel alloc]init];
[locationTitle setTranslatesAutoresizingMaskIntoConstraints:NO];
locationTitle.backgroundColor = [UIColor whiteColor];
[self addSubview:locationTitle];
}
return self;
}
#end
I think this is because the loadView method are invoke earlier than viewDidLoad method.
so when you set _locationView.locationImageFile = #"320x213-1.png";,the containerView's image are not being set.
You can consider declare locationImageContainer as a property of locationView , and set it's image directly.like
_locationView.locationImageContainer.image = [UIImage imageNamed:#"320x213-1.png"];
instead of setting locationImageFile as a property.
When LocationView is initialized, the value of the instance variable locationImageFile equals nil. Override the setter of the locationImageFile property inside LocationView.m like this:
- (void)setLocationImageFile:(NSString *)aLocationImageFile
{
locationImageFile = aLocationImageFile;
locationImageContainer.image = [UIImage imageNamed:aLocationImageFile];
}
You can try, doing it like this:
_locationView.locationImageFile = [UIImage imageNamed:locationImageFile];
if you did it like this:
_locationView.locationImageFile = locationImageFile;
I have 2 view controllers, the first is a storyboard (this is root) and the second with is nibless. When I press a button in the root view controller it should call the second controller.
Here the code for my second view controller:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UILabel *sampleLabel = [[UILabel alloc] initWithFrame: CGRectMake(0,0,100,100)];
UIImageView * basketItem = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"B.jpg"]];
[self.view addSubview:sampleLabel];
[self.view addSubview:basketItem];
NSLog(#"%#",self.view.subviews);
sampleLabel.text = #"Main Menu";
}
return self;
}
self.view.sebviews query shows that 2 objects label and imageView objects exists, but in fact I see black screen only.
Here is transition method
- (void)transitionToViewController:(UIViewController *)aViewController
withOptions:(UIViewAnimationOptions)options
{
aViewController.view.frame = self.containerView.bounds;
[UIView transitionWithView:self.containerView
duration:0.65f
options:options
animations:^{
[self.viewController.view removeFromSuperview];
[self.containerView addSubview:aViewController.view];
}
completion:^(BOOL finished){
self.viewController = aViewController;
}];
}
Move the code in viewDidLoad. Here you are sure the view has been loaded into memory and hence can be further customized.
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *sampleLabel = [[UILabel alloc] initWithFrame: CGRectMake(0,100,100,100)];
UIImageView * basketItem = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"B.jpg"]];
[self.view addSubview:sampleLabel];
[self.view addSubview:basketItem];
NSLog(#"%#",self.view.subviews);
sampleLabel.text = #"Main Menu";
}
If you are not using ARC, pay attention to memory leaks.
Note
I really suggest to read Apple doc for this. You should understand how things work. Hope that helps.
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
Edit
I don't know what the problem could be. To make it work, try to override loadView (in MenuViewController) method like the following:
- (void)loadView
{
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame];
contentView.backgroundColor = [UIColor redColor]; // red color only for debug purposes
self.view = contentView;
}
Leave the viewDidLoad method as I wrote and see what happens.
When you create the view controller use only init method.
MenuViewController *vc = [[MenuViewController alloc] init];
Your UILabel's frame has size.width=0:
CGRectMake(0,100,0,100)
and if B.jpg is not added to the project you UIImageView will also be empty.
Also, if second UIViewController doesn't have a XIB, initialize it using the - (id)init method instead of - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil.
I have a UIScrollView with a UIView inside. I want to lock the x-axis so that the view is only scrolled vertically. How do I enable directional locking?
First, set the UIScrollView's contentSize to have a width that is equal to or less than the width of the UIScrollView's frame.
Next, set UIScrollView's alwaysBounceHorizontal to NO. This will prevent the scroll view from "rubber banding" even though you've told it there's no more horizontal content to display.
UIScrollView *scrollView;
CGSize size = scrollView.contentSize;
size.width = CGRectGetWidth(scrollView.frame);
scrollView.contentSize = size;
scrollView.alwaysBounceHorizontal = NO;
It doesn't matter what's actually inside the scroll view.
Swift 5.0
let scrollView = UIScrollView() // Or however you want to initialize it
var size = scrollView.contentSize
size.width = scrollView.frame.width
scrollView.contentSize = size
scrollView.alwaysBounceHorizontal = false
You'll be subclassing UIScrollView and overriding the touchesBegan:withEvent: method, touchesMoved:withEvent: method, and the touchesEnded:withEvent: method.
You'll use those methods, along with the start and end points of a touch, to calculate what kind of touch event took place: was it a simple tap, or a horizontal or vertical swipe?
If it is a horizontal swipe, you cancel the touch event.
Take a look at the source code here to learn how you might get started.
#import <UIKit/UIKit.h>
#interface DemoButtonViewController : UIViewController <UIScrollViewDelegate>
#property (nonatomic, strong) UIScrollView *filterTypeScrollView;
#property (nonatomic, strong) UIBarButtonItem *lockButton;
- (void)lockFilterScroll:(id)sender;
#end
#import "DemoButtonViewController.h"
#implementation DemoButtonViewController
#synthesize filterTypeScrollView;
#synthesize lockButton;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor darkGrayColor];
self.filterTypeScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 130, self.view.frame.size.width, 320)];
filterTypeScrollView.contentSize = CGSizeMake(self.view.frame.size.width*4, 320);
filterTypeScrollView.pagingEnabled = YES;
filterTypeScrollView.delegate = self;
[self.view addSubview:filterTypeScrollView];
UIToolbar *lockbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 450, self.view.frame.size.width, 30)];
lockbar.barStyle = UIBarStyleBlackTranslucent;
self.lockButton = [[UIBarButtonItem alloc] initWithTitle:#"Lock Filter Scroll" style:UIBarButtonItemStylePlain target:self action:#selector(lockFilterScroll:)];
[lockbar setItems:[NSArray arrayWithObjects:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],lockButton,nil]];
[self.view addSubview:lockbar];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)lockFilterScroll:(id)sender
{
filterTypeScrollView.scrollEnabled = !filterTypeScrollView.scrollEnabled;
if (filterTypeScrollView.scrollEnabled)
{
[lockButton setTitle:#"Lock Filter Scroll"];
}
else {
[lockButton setTitle:#"Unlock Filter Scroll"];
}
}
#end