When I animate the custom view, the height of the view changes - ios

My xib of BetRecordAniChooserView :
My ViewController in simulator:
You can see the background view of the chooser-view height is reduce.
My code is below:
BetRecordAniChooserView.h:
#import <UIKit/UIKit.h>
typedef void(^ChooseBlock)(NSString *choosedStr);
#interface BetTRecordAniChooserView : UIView
#property (nonatomic, assign) UIViewController *owener;
#property (nonatomic, assign) BOOL isShow;
#property (nonatomic, copy) ChooseBlock block;
- (void)showSelf;
- (void)hideSelf;
#end
BetRecordAniChooserView.m:
#import "BetTRecordAniChooserView.h"
#interface BetTRecordAniChooserView ()
#property (weak, nonatomic) IBOutlet UIButton *all_button;
#property (weak, nonatomic) IBOutlet UIButton *check_pending_button;
#property (weak, nonatomic) IBOutlet UIButton *deposited_button;
#property (weak, nonatomic) IBOutlet UIButton *have_cancel_button;
#end
#implementation BetTRecordAniChooserView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (void)awakeFromNib {
[super awakeFromNib];
self.frame = CGRectMake(0, 0, self.bounds.size.width, 100);
self.all_button.selected = YES;
}
#pragma mark - actions
- (IBAction)allAction:(UIButton *)sender {
self.block(sender.titleLabel.text);
}
- (IBAction)checkPendingAction:(UIButton *)sender {
self.block(sender.titleLabel.text);
}
- (IBAction)haveDepositeAction:(UIButton *)sender {
self.block(sender.titleLabel.text);
}
- (IBAction)haveCancelAction:(UIButton *)sender {
self.block(sender.titleLabel.text);
}
#pragma mark - methods
- (void)showSelf {
CGRect temp_frame = self.frame;
self.isShow = YES;
[UIView animateWithDuration:0.3 animations:^{
self.frame = CGRectMake(temp_frame.origin.x, temp_frame.origin.y + temp_frame.size.height, temp_frame.size.width, temp_frame.size.height);
}];
}
- (void)hideSelf {
CGRect temp_frame = self.frame;
self.isShow = NO;
[UIView animateWithDuration:0.3 animations:^{
self.frame = CGRectMake(temp_frame.origin.x, temp_frame.origin.y - temp_frame.size.height, temp_frame.size.width, temp_frame.size.height);
} completion:^(BOOL finished) {
}];
}
#end
In my ViewController.m:
#import "ViewController.h"
#import "BetTRecordAniChooserView.h"
#interface ViewController ()
{
BetTRecordAniChooserView *_chooser_view;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_chooser_view = [[NSBundle mainBundle] loadNibNamed:#"BetTRecordAniChooserView" owner:self options:nil].firstObject;
//float width = self.view.bounds.size.width;
//float height = 100.f;
//_chooser_view.frame = CGRectMake(0, -height + 64, width, height);
_chooser_view.owener = self;
[self.view addSubview:_chooser_view];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionA:(UIButton *)sender {
if (_chooser_view.isShow) {
[_chooser_view hideSelf];
} else {
[_chooser_view showSelf];
}
}
#end
You can see in the BetRecordAniChooserView's awakeFromnNib method:
The frame height I set 100:
self.frame = CGRectMake(0, 0, self.bounds.size.width, 100);
But when I start my simulator it become 36(the gray color view under the buttons).
(lldb) po self.frame
(origin = (x = 0, y = 0), size = (width = 375, height = 36))

I found the reason:
At first I was use the trailing, leading, bottom, top of the gray back view to its superview, I get this issue.
And then I delete the Bottom Space Constraint, and add the height constraint to it.
Then I do not have the issue again, and I can drag out the height Constraint to the .m file too, convenience to change the height.
But I don't know if there is a method I do not use my set height constraint method, still use the trailing, leading, bottom, top constraints to get the requirement effect.

Related

UIView Animation Removes layer.cornerRadius After Completion

I have a UILabel that I am animating the constraints for so that it drop down into view. I am using layer.cornerRadius to give the view rounded corners, but for whatever reason after the animation completes the corner radius is removed.
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseInOut animations:^{
if (shouldShow) {
self.labelOverMapTopConstraint.constant = 16;
} else {
self.labelOverMapTopConstraint.constant = -40;
}
[self.view layoutIfNeeded];
} completion:nil];
cornerRadius is set in viewDidLoad.
Is there a way to prevent this from happening?
I suspect you're subclassing UILabel here since it looks like you have padding in there, is that correct?
There could be something going awry with any custom drawing/calculations you're doing in there, so it would probably be helpful to post that code for inspection as well.
A few questions:
Do you have masksToBounds set to YES?
If you're not using a custom UILabel subclass, are you wrapping the label in a view?
How is the animation being triggered? Is it by a button? A callback from a NSURLRequest? If it's triggered by an async callback are you jumping back on the main queue to perform the animation?
If the animation is triggered automatically within the lifecycle, which lifecycle method is it triggered in?
I wasn't able to reproduce the issue in a test project with a vanilla UILabel. I then tried it with a UILabel subclass which includes additional padding and still wasn't able to reproduce it there.
I've included example code snippets below:
#import "ViewController.h"
#import "R4NInsetLabel.h"
#interface ViewController ()
#property BOOL showingToast;
#property (strong, nullable) IBOutlet R4NInsetLabel *toastLabel;
#property (strong, nullable) IBOutlet NSLayoutConstraint *toastLabelTopConstraint;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.titleTextAttributes = #{NSForegroundColorAttributeName : [UIColor whiteColor]};
self.showingToast = NO;
// start with the label pushed off the top of the screen
self.toastLabelTopConstraint.constant = -40.0f;
self.toastLabel.layer.cornerRadius = 6.0f;
self.toastLabel.layer.masksToBounds = YES;
}
- (IBAction)toggleToast:(id)sender {
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseInOut animations:^{
if (self.showingToast == NO) {
self.toastLabelTopConstraint.constant = 16;
self.showingToast = YES;
} else {
self.toastLabelTopConstraint.constant = -40;
self.showingToast = NO;
}
[self.view layoutIfNeeded];
} completion:nil];
}
#end
#import "R4NInsetLabel.h"
IB_DESIGNABLE
#interface R4NInsetLabel()
#property IBInspectable CGFloat contentPadding;
#property (nonatomic) UIEdgeInsets contentInsets;
- (CGSize)_addInsetsToSize:(CGSize)size;
#end
#implementation R4NInsetLabel
- (UIEdgeInsets)contentInsets {
return UIEdgeInsetsMake(self.contentPadding, self.contentPadding, self.contentPadding, self.contentPadding);
}
- (CGSize)_addInsetsToSize:(CGSize)size {
CGFloat width = size.width + self.contentInsets.left + self.contentInsets.right;
CGFloat height = size.height + self.contentInsets.top + self.contentInsets.bottom;
return CGSizeMake(width, height);
}
- (void)drawTextInRect:(CGRect)rect {
CGRect insetRect = UIEdgeInsetsInsetRect(rect, self.contentInsets);
[super drawTextInRect:insetRect];
}
- (CGSize)intrinsicContentSize {
CGSize baseSize = [super intrinsicContentSize];
return [self _addInsetsToSize:baseSize];
}
- (CGSize)sizeThatFits:(CGSize)size {
CGSize baseSize = [super sizeThatFits:size];
return [self _addInsetsToSize:baseSize];
}
#end
And here's what it looks like:
You also need to set the corner radius on viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
label.layer.cornerRadius = yourValue
}

Subclass UITextField to add blank space in begining by default [duplicate]

This question already has answers here:
How to add space at start of UITextField
(8 answers)
Closed 6 years ago.
I want to add blank space in the beginning of my UITextField. I am subclassing my UITextfield with the following code. I am not sure what is going wrong here
- (CGRect)textRectForBounds:(CGRect)bounds {
return CGRectMake(bounds.origin.x + 15, bounds.origin.y + 15, bounds.size.width, bounds.size.height);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return CGRectMake(bounds.origin.x + 15, bounds.origin.y + 15, bounds.size.width, bounds.size.height);
}
Thanks in Advance
Try this
UILabel * leftView = [[UILabel alloc] initWithFrame:CGRectMake(10,0,7,26)];
leftView.backgroundColor = [UIColor clearColor];
textField.leftView = leftView;
textField.leftViewMode = UITextFieldViewModeAlways;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
How to add space at start of UITextField
You should override textRectForBounds and editingRectForBounds like this:
CustomTextField.h:
#import <UIKit/UIKit.h>
#interface CustomTextField : UITextField
#property CGFloat inset;
#end
CustomTextField.m:
#import "CustomTextField.h"
#implementation CustomTextField
- (CGRect)textRectForBounds:(CGRect)bounds {
CGRect rect = CGRectInset(bounds, _inset, 0);
return rect;
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
CGRect rect = CGRectInset(bounds, _inset, 0);
return rect;
}
#end
ViewController.m:
#import "ViewController.h"
#import "CustomTextField.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet CustomTextField *textField;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_textField.inset = 20;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The result:

When using JSQMessagesViewController as detailView in UISplitviewCOntroller, KeyBoardToolBar needs to appear in DetailViewController only

When using JSQMessagesViewController as detailView in UISplitViewController, KeyBoardToolBar needs to appear in DetailViewController only
late answer...
if u want to reduce the inputToolbar you need to create a subclass of JSQMessagesToolbarContentView and provide your own view for the tool bar's content view.
below i am giving the sample example, create a subcalss of JSQMessagesToolbarContentView name it as JSQMessagesToolbarContentView_custom in the subcalss add below code,
#import "JSQMessagesToolbarContentView.h"
#interface JSQMessagesToolbarContentView_custom : JSQMessagesToolbarContentView
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *holderViewLeadingConstraint;
#end
and in JSQMessagesToolbarContentView_custom.m file,
#import "UIView+JSQMessages.h"
#import "JSQMessagesToolbarContentView_custom.h"
#implementation JSQMessagesToolbarContentView_custom
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass([JSQMessagesToolbarContentView_custom class])
bundle:[NSBundle bundleForClass:[JSQMessagesToolbarContentView_custom class]]];
}
#pragma mark - Initialization
- (void)awakeFromNib
{
[super awakeFromNib];
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
self.backgroundColor = [UIColor clearColor];
}
//below method will place the contentview to desired position
- (void)layoutSubviews
{
[super layoutSubviews];
self.holderViewLeadingConstraint.constant = 320;
}
#pragma mark - Setters
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
[super setBackgroundColor:backgroundColor];
self.leftBarButtonContainerView.backgroundColor = backgroundColor;
self.rightBarButtonContainerView.backgroundColor = backgroundColor;
}
- (void)setLeftBarButtonItem:(UIButton *)leftBarButtonItem
{
[super setLeftBarButtonItem:leftBarButtonItem];
}
- (void)setLeftBarButtonItemWidth:(CGFloat)leftBarButtonItemWidth
{
// self.leftBarButtonContainerViewWidthConstraint.constant = leftBarButtonItemWidth;
[self setNeedsUpdateConstraints];
}
- (void)setRightBarButtonItem:(UIButton *)rightBarButtonItem
{
[super setRightBarButtonItem:rightBarButtonItem];
}
- (void)setRightBarButtonItemWidth:(CGFloat)rightBarButtonItemWidth
{
// self.rightBarButtonContainerViewWidthConstraint.constant = rightBarButtonItemWidth;
[self setNeedsUpdateConstraints];
}
- (void)setRightContentPadding:(CGFloat)rightContentPadding
{
// self.rightHorizontalSpacingConstraint.constant = rightContentPadding;
[self setNeedsUpdateConstraints];
}
- (void)setLeftContentPadding:(CGFloat)leftContentPadding
{
// self.leftHorizontalSpacingConstraint.constant = leftContentPadding;
[self setNeedsUpdateConstraints];
}
#pragma mark - UIView overrides
- (void)setNeedsDisplay
{
[super setNeedsDisplay];
[self.textView setNeedsDisplay];
}
//return the custom view that we are going to create next
- (JSQMessagesToolbarContentView_custom *)loadToolbarContentView
{
NSArray *nibViews = [[NSBundle bundleForClass:[JSQMessagesToolbarContentView_custom class]] loadNibNamed:NSStringFromClass([JSQMessagesToolbarContentView_custom class]) owner:nil options:nil];
return nibViews.firstObject;
}
after this you need to create add new .xib file name it as JSQMessagesToolbarContentView_custom.xib this file contains our small content view for the inputToolbar and more importantly set the out let connections as doing the demo example and aslo set the view class name to JSQMessagesToolbarContentView_custom. hear i can only add image of the custom view.
now create a outlet for leading constraint to reduce the size of the content view as give below,
and add the constraints outlet's as given in the demo. so if u add some constrians without modifying the base class it will give error or runtime error so edit the base class also
now go to JSQMessagesToolbarContentView.h and add the blow properties form JSQMessagesToolbarContentView.m just cut and past and make it public.
#interface JSQMessagesToolbarContentView : UIView
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *leftBarButtonContainerViewWidthConstraint;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *rightBarButtonContainerViewWidthConstraint;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *leftHorizontalSpacingConstraint;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *rightHorizontalSpacingConstraint;
//...rest of the code
now in the JSQMessagesInputToolbar.m file, in order to make the tool bar transperent for half of the splitview,
- (void)awakeFromNib
{
[super awakeFromNib];
//...rest of the code
[self setBackgroundImage:[UIImage new]//imageNamed:#"topbar"]
forToolbarPosition:UIToolbarPositionAny
barMetrics:UIBarMetricsDefault];
[self setShadowImage:[UIImage new] forToolbarPosition:UIBarPositionAny];
[self setBackgroundColor:[UIColor clearColor]];
}
thats it now run the project, and change the leading constraints constant you see below output,

View Delegate Not Being Called

I'm building a graphing app, and I have a view and a view controller, which acts as a delegate for the view (to retrieve information). While I haven't started the actual drawing yet, I am currently trying to store values in a dictionary; however, I have certain NSLogs placed methodically across the view controller and I noticed that the delegate methods I call from the view don't get called at all. For example, I call my scaleForGraph function, but it does not execute. Being new to this, I'm not sure if there's something I'm missing. FYI: I have no errors, it compiles and executes. I've tried to slim the code down as much as possible. Thank you for your help!
Here's the .h for my view, where I define the protocol:
// GraphView.h
#import <UIKit/UIKit.h>
#class GraphView;
#protocol GraphViewDelegate <NSObject>
- (float)scaleForGraph:(GraphView *)requestor;
-(NSMutableDictionary*) valuesForGraph:(GraphView *)requestor withWidth:(float) width;
#end
#interface GraphView : UIView
#property (nonatomic) id <GraphViewDelegate> delegate;
#property (nonatomic) id expressionCopy;
#end
And here's the .m:
#import "GraphView.h"
#implementation GraphView
#synthesize expressionCopy = _expressionCopy;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.contentMode = UIViewContentModeRedraw;
}
return self;
}
- (void)awakeFromNib
{
self.contentMode = UIViewContentModeRedraw;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat width = screenSize.width;
CGFloat height = screenSize.height;
float scale = [self.delegate scaleForGraph:self];
NSLog([NSString stringWithFormat:#"My Scale: %f",scale]); //always returns 0
NSMutableDictionary *graphValues = [self.delegate valuesForGraph:self withWidth:width];
}
#end
And here's my view controller .h:
#import <UIKit/UIKit.h>
#import "GraphView.h"
#interface GraphingViewController : UIViewController <GraphViewDelegate>
#property (weak, nonatomic) IBOutlet GraphView *graphView;
#property (strong, nonatomic) IBOutlet UIStepper *stepper;
- (IBAction) changedScale:(UIStepper *)stepper;
#property (nonatomic) int scale;
#property (nonatomic) id expressionCopy;
#end
And here's the .m for the controller:
#import "GraphingViewController.h"
#interface GraphingViewController ()
#end
#implementation GraphingViewController
#synthesize expressionCopy = _expressionCopy;
- (void)updateUI
{
self.stepper.value = self.scale;
[self.graphView setNeedsDisplay];
}
- (void)setScale:(int)scale
{
if (scale < 0) scale = 0;
if (scale > 100) scale = 100;
_scale = scale;
[self updateUI];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)changedScale:(UIStepper *)stepper {
self.scale = stepper.value; //this function works fine, but is not delegate/does not get called by view
}
-(float) scaleForGraph:(GraphView *)requestor {
NSLog(#"HI"); //never gets here
}
-(NSMutableDictionary*) valuesForGraph:(GraphView *)requestor withWidth:(float) width {
NSLog(#"Hello2"); //never gets here
}
return xyVals;
}
#end
Nowhere in the code you've posted do you tell your GraphView that the GraphingViewController is it's delegate. So, you are sending a message to nil.
You'll want to do something like:
self.graphView.delegate = self;
In your GraphingViewController setup code.
Make your controller actual delegate of GraphView. You can do it in interface builder by Ctrl-dragging from GraphView to the object (orange circle in the bottom) and than choose "delegate"

Can't zoom UIScrollView on iOS 6

There is my .m code.
#import "ScrollZoomViewController.h"
#interface ScrollZoomViewController () <UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#end
#implementation ScrollZoomViewController
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
NSLog(#"zooming");
return self.imageView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.minimumZoomScale = 0.5f;
self.scrollView.maximumZoomScale = 5.0f;
self.scrollView.delegate = self;
self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
self.scrollView.contentSize = self.imageView.image.size;
}
I'm using Xcode 4.5 and iOS 6.0 and AutoLayout closed.
Image can scroll but can't zoom. Is this because iOS 6?
You need set value for zoomScale property so as to start zooming.
Add following line after setting contentSize of scrollView.
self.scrollView.zoomScale = minimumZoomScale;
Try to remove this code:
self.scrollView.contentSize = self.imageView.image.size;
and add more content size, instead of image size.
Ex: you need to add like self.scrollView.contentSize = CGSizeMake(1770, 2346);
Hope this will solve.

Resources