Basically, what I want to do is detect when a user scrolls inside a text view, and then hide a label (Smoothly fade out, if possible). (The label indicates to scroll to view the rest of the text, but I don't want it to still show after the user has done so.)
If you could include in your answer the code used in the h/m files, it would be greatly appreciated.
Updated code for future reference:
.h
#interface myViewController : UIViewController
#property(nonatomic,retain) IBOutlet UILabel *label;
.m
#synthesize label;
- (void)scrollViewDidScroll:(UIScrollView *)textView
{
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0;
}];
}
Then make sure to set the UITextView delegate to self.
You can use UIScrollView's delegate method – scrollViewDidScroll: to detect that the user has scrolled, and fade out your label with a UIView animation block, like so:
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0
}];
Related
I'm very new to programming and objective c so please go easy on me.
I would like a UIButton (which I'm using as an IBAction) to change an the image in a UIImageView when pressed. I put the UIImageView into a UIScrollView in the storyboard but I hope I can still programmatically change the image.
I have searched absolutely everywhere for an answer for hours but nothing has worked for me either because it wasn't the right solution or I didn't do it properly.
I have tried this code and some more but they always return a "Thread 1: signal SIGABRT" when I press the button:
imageView.image = [UIImage imageNamed: #"Ruler pic inch.png"];
Here is my code so far:
ViewController.h
#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
#interface ViewController : UIViewController <ADBannerViewDelegate, UIScrollViewDelegate> {
ADBannerView *adView;
BOOL bannerIsVisible;
IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageView;
IBOutlet UIButton *proVersion;
IBOutlet UIButton *howToUse;
}
- (IBAction)switchUnit:(id)sender;
#property (nonatomic, assign) BOOL bannerIsVisible;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize bannerIsVisible;
#synthesize scrollView;
#synthesize imageView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Hide status bar:
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// iAd:
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.frame = CGRectOffset(adView.frame, 0, -50.0f);
[self.view addSubview:adView];
adView.delegate=self;
self.bannerIsVisible=NO;
// Setting scrollview content size to size of image
scrollView.contentSize = CGSizeMake(320,2246);
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!self.bannerIsVisible) {
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, 50.0f);
[UIView commitAnimations];
self.bannerIsVisible = YES;
}
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (self.bannerIsVisible) {
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, -50.0f);
[UIView commitAnimations];
self.bannerIsVisible = NO;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)switchUnit:(id)sender {
// CODE THAT MAKES IMAGE CHANGE GOES HERE (I thought...)
}
#end
Help would be greatly appreciated. I'm fed up with it. I've probably done a silly mistake somewhere but I can't work it out. Thanks in advance.
General pointers:
Try to use #property for all your instance variables (it'll server you well in future)
Don't use #synthesize (the compiler does a better job of it for you)
If you have a property bob, access it by using self.bob
Turn on ARC (looks like you don't have it on currently)
Best not to have any spaces in image names
To be clear on properties, when you have a property you don't need to create instance variables in between {} of the #interface. These should be removed in order to prevent multiple definitions. The auto-synthesising done by the compiler will define the instance variables for you but you should always use the property to access the value (as in item 3 above).
That said, your - (IBAction)switchUnit:(id)sender looks fine, if a little empty. The code should be something like:
self.imageView.image = [UIImage imageNamed:#"Ruler_pic_inch.png"];
For it to work, the image Ruler_pic_inch.png would need to be in your bundle (which means it's in Xcode project and set to copy during the build.
Again, that said, your problem would seem to relate to you being confused somewhere. SIGABRT type issues would usually be picked up by the compiler and notified to you as a warning saying something like "some object may not respond to some selector". If you see any of those, look at them and work out why you're trying to ask the object a question it doesn't understand.
If you don't see any compiler warnings, then you've told the compiler that an object is going to be of one type and then actually set it to something else. In this case I'd look at your IBOutlets in Storyboard and check that they are actually set to the correct destination view (disconnect and reconnect them all to be sure).
I have an iPad view that has a ScrollView, and below that I'm using a Page Control Object to show what page it is on. Elsewhere on the screen, I have a timeline between say 12:00 AM and 5:00 AM - as time progresses, there is a UIImage that gets wider on top of the timeline to indicate the time of day. The UIImage gets wider as the day goes on through the use of an NSTimer that kicks off every minute or so.
In addition, I have 3 buttons on the page that will refresh the Scrollview with a new set of images inside of it. The number of images can be varied, anywhere between 3 and 7. So, when a button is pressed, I update the scrollview, and also update the Page Control object to set the "numberOfPages" property to the appropriate number.
OK, so the problem seems to be that whenever I click a button and the pageControl numberOfPages is changed, the UIImage reverts back to whatever size it was back when I originally designed it in Interface Builder (the storyboard).
I created a simplified example project that hopefully has enough to recreate the behavior...
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *btnTest;
#property (weak, nonatomic) IBOutlet UIImageView *imgTest;
#property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
- (IBAction)buttonPress:(id)sender;
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize imgTest,btnTest,pageControl;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Set up an observer to handle updating the timeline
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(UpdateWidth:)
name:#"UpdateWidth" object:nil];
}
-(void)viewDidAppear:(BOOL)animated {
// Send an updateTimeIndicator notification when screen loads.
[[NSNotificationCenter defaultCenter] postNotificationName:#"UpdateWidth" object:#"sent"];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonPress:(id)sender {
pageControl.numberOfPages = 7;
pageControl.currentPage = 0;
}
-(void)UpdateWidth:(NSNotification *)notification{
[imgTest setFrame:CGRectMake([imgTest frame].origin.x, [imgTest frame].origin.y,
450, [imgTest bounds].size.height)];
imgTest.contentMode = UIViewContentModeScaleAspectFit; // This determines position of image
imgTest.clipsToBounds = YES;
[imgTest setNeedsDisplay];
NSLog(#"Width Updated");
}
#end
So, in this example, I have just 3 objects in the Window - the PageControl, a Button, and a UIImage that has the background set to blue. I'm using the Notification Center to send messages as to when to resize the UIImage (in this case, I'm only doing it once, when the view appears). The updateWidth routine sizes the UIImage to be 450 pixels wide, and the view appears as it should.
However, tapping the button will change the numberOfPages value, and in so doing, sets the UIImageView back to the size that it was when it was originally laid out in Interface Builder.
I do have a zipped project file if anyone would like to see it. Also, I did try this without using the Notification Center and the results were the same (I originally wasn't using the Notification Center, just thought it might give different results).
I can probably get by without using the PageControl object, but I'm now very curious as to why happens. Thanks!
I seem to have solved the problem by placing both the ScrollView and the PageControl objects into their own (new) UIView. To do this, I opened the storyboard in interface builder, drug a View object from the toolbox out to the interface window, and then placed both the existing ScrollView and the PageControl objects into the new UIView. Afterwards, changing the numberOfPages property of the PageControl did not affect anything else on the window.
I'm still confused as to this behavior though. I'm guess that because once the page control was placed in a new view and the problem stopped, that the PageControl wants to update the entire view that it is in when the numberOfPages property is changed.
I've a subclass of UIView with a UILabel with is added as subview to the view. In the layoutSubviews method the position and height of the UILabel is calculated. My problem is, that this height should be recalculated, when the text of the UILabel changes. The text is inserted into the label from the UIViewController, so the view does not know when this happen.
You can subclass UILabel to override setText: like this:
#implementation MyLabel
- (void)setText:(NSString *)text {
[super setText:text];
[self.superview setNeedsLayout];
}
I have this class:
Header:
#interface vcMain : NSWindowController {
IBOutlet NSView *scroll;
}
#property (retain) IBOutlet NSView *scroll;
-(IBAction)test:(id)sender;
#end
Source:
#implementation vcMain
#synthesize scroll;
-(IBAction)test:(id)sender {
vItem *item = [[vItem alloc] initWithNibName:#"vItem" bundle:nil];
NSView *view = [item view];
[view setFrame:NSMakeRect(0, 0, 300, 600)];
[view setAutoresizingMask:( NSViewHeightSizable) ];
[scroll addSubview:view];
}
#end
*scroll is a Custom View in a Bordered Scroll View in the Content View of a Window.
vItem is a ViewController subclass with some things on it to identify its position.
Problem: When resizing my vcMain from the default 300x600 to 150x300, I don't see any scrollbars.
What am I doing wrong?
Tom
Solved
It was simple, actually. Resizing the view apparently also resized the subview so it wasn't neccessary to show the scrollbars - however, as the elements in the subview didn't move, I didn't notice that the subview was resizing.
Solved by correcting the resizing of the view.
Does anyone know how to slide in a UIDatePicker with a Done button like the keyboard control? If so, can you share some sample code on how. Thanks
I suggest you use a UIViewController, and show it modally.
Create UIViewController and setup the view with OK-button in Interface Builder, as you would for any view controller.
And display it using:
- (void)presentModalViewController:(UIViewController *)modalViewController
animated:(BOOL)animated
You can set the root views background to clear if you want it transparent. And optionaly animate it to cemi-transparent black when the transition has finished. Something like this would work:
- (void)viewDidAppear:(BOOL)animated {
if (animated) [UIView beginAnimations:#"fadeDark" context:NULL];
self.view.backgroundColor = [UIColor colorWithWithe:0.0f alpha:0.5f];
if (animated) [UIView commitAnimations];
}
1.create a subclass of the UIButton class
2.redeclare inputview as read-write
#property (nonatomic, strong, readwrite) UIView *inputView;
3.set canBecomeFirstResponder to YES
- (BOOL)canBecomeFirstResponder {
return YES;
}
4.set inputview as datepicker
self.inputView = self.datePicker;
5.set UIResponder to firstResponder when you want
[self becomeFirstResponder];
5.you can see datepicker slide in like keyboard