Making a UILabel subview in UIScrollView to be firstResponder - uiscrollview

I have added a label with some text and links to an ScrollView,
when you tap on those links (in the label), a delegate method will call, displays a popover and show some related information.
but problem starts from here, I want when you tap on anywhere else except the links, the popover disappear.
if I add a UITapGestureRecognizer to ScrollView, the delegate method for links won't call.
what should I do to label handles the tap on links, and ScrollView Handles the other taps?
I did like that:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped)];
[self.scrollView addGestureRecognizer:tap];
- (void)tapped
{
if ([self.storyText.delegate respondsToSelector:#selector(attributedLabel:shouldFollowLink:)])
[self.storyText.delegate performSelector:#selector(attributedLabel:shouldFollowLink:) withObject:self.storyText];
}
In tapped method Im checking if Im tapping on a link, the delegate should be called, but Delegate wont call.
Am I missing someThing?

You can use custom UIButtons instead of labels or you can place custom UIButtons with clear background color over the links and give actions to this buttons.

Solved!
Solution:
first I create a custom class for my scrollView and subclassed that from UIScrollView.
Second I override
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
in my custom ScrollView class. in this method I called a method to dismiss the popover.
but important part is that in viewWillAppear method of the class which popover will appear, I passed self to custom scrollView class. because if I didn't that, the method for dismissing popover won't work (it needs an object of this class).
[self.scrollView initWithStoryViewController:self];
this images show in which scenario I had this problem:

Related

Knowing when NSPopoverTouchBarItem will show its collapsed view

I have an NSPopoverTouchBarItem in my Touch Bar, created in Interface Builder.
The popover has a custom NSView inside it, and want to load data in it only when the view is activated, but I can't find any way to recognize when the contained NSTouchBar or NSView becomes visible.
According to docs, NSTouchBarDelegate does not have any delegate methods for the view appearing, either.
Which class should I subclass, or should I be monitoring viewWillDraw on my custom NSView and set up some hacky scheme?
The docs were not too clear, but subclassing NSPopoverTouchBarItem gives you -(void)showPopover:(id)sender and -(void)dismissPopover:(id)sender.
You can then define a delegate method to tell the parent class that this popover did show.
-(void)showPopover:(id)sender {
[super showPopover:sender];
[self.delegate touchPopoverDidShow];
}

IBAction not triggering NSView drawing

I'm missing something fundamental about NSView. I have a Cocoa Application with an Objective C class named DataSource that is just a regular class, it's not in the nib. The data source has a single instance variable, an NSColor *, and it has a getter and setter.
The view class instantiates the DataSource in awakeFromNib:
- (void)awakeFromNib{
NSLog(#"awakeFromNib");
ds = [[DataSource alloc] init];
}
and then queries the DataSource for the color to use in drawRect. It works fine. I also implement
- (void)mouseDown:(NSEvent *) anEvent;
in the view class, change the color of the DataSource, and then call
[self setNeedsDisplay:YES];
and it also works as I expect when I click in the custom view.
But if I hook up a button in the nib, wired to this IBAction in the view class:
- (IBAction)buttonPushed:(id) sender {
NSLog(#"buttonPushed");
[ds setData:[NSColor cyanColor]];
[self setNeedsDisplay:YES];
}
the data source updates, but drawRect is never called, despite setNeedsDisplay. In my more complicated version, if I click in the view (in a way that doesn't change the color), I will then get the update (caused by the button). Something is delaying drawing. How can I fix this?
Update: There is no controller and there are no outlets. The NSView subclass contains buttonPushed. The data source updates immediately upon button push, but drawing is delayed, despite calling setNeedsDisplay:YES from the view class. Drawing is delayed indefinitely, unless something else happens to trigger it.
Where is the IBAction located? Are you using some view controller? Is the NSView an outlet in that controller?

Dismiss Keyboard from TextField in a custom

In the UITableViewController is using custom cells. In the custom cell there is a TextField. Need to dismiss the the keyboard when the user touches outside of the keyboard. In the custom cell's .m file have added this code;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[holeScoreTextField resignFirstResponder];
}
This does work for when the user touches another cell or inside the same cell. Issue is that in the UITableViewController is a view with some information. The above code does not work for that view.
A very quick, dirty, and simple solution is to simply create a full screen sized invisible button over the entire screen. The keyboard will always appear over the top of that view.
Hide the view on viewWillAppear: and textFieldShouldEndEditing:, and show it on textFieldShouldBeginEditing:.
Should work like a charm.

UIScrollView subviews and setNeedsDisplay

I've the following problem :
I have a UIView containing a UIScrollView as a subview. (nib file).
Programmatically I add several subviews (UIImageView) to the UIScrollView, each UIImageview contains an image loaded from the net asynchronously, so I need to update the scrollView when the images are downloaded. In the class responsible of the images fetching, I advertise the the View controller responsible to manage the scrollView, using this code
[[(MosaicViewController *)data] scrollView setNeedsDisplay];
the Ivar data is a pointer to the ViewController.
This stuff don't work,no reload of the scrollView happen
To be sure that the call is triggered I wrote a method inside the viewController containing the scrollView, and inside this method I called setNeedsDisplay,
[(MosaicViewController *)data updateView];
-(void) updateView
{
NSLog(#"setNeedsDisplay");
[self.scrollView setNeedsDisplay];
}
the method updateView is triggered correctly, I mean is called after each Image is downloaded, but the scrollView contents isn't updated. In the ViewController containing the scrollView I don't implement the drawRect method, could be this the reason for the lack of update after calling setNeedsDisplay?
Any help/suggestion/reference etc.. is welcome
Thanks in advance
Dude are you doing imageView.image = downloadedImage ??
Also you should not have to do [self.scrollView setNeedsDisplay] since you did not change anything on scrollView !!
What changed is the content of the imageView and imageView.image = downloadedImage will automatically trigger setNeedsDisplay on imageView !!
Some other check points
Is scrollView visible?
Is scrollView.contentSize set??
Is the scrollView frame correct ??

Hide/Unhide UINavigationbar when the screen is tapped

I'm very new with iOS Development and I have just created one of my first apps, in my .xib file I have a UINavigationBar that I want to hide/show when a part of the screen is tapped by the user (like in the Photo app). I've found some snippets online but I don't know where and how to use those.
I'd appreciate a lot if somebody could give me detailed informations about how to do this.
Add this toggle method anywhere in your UIViewController. This hides on first tap and shows again in second tap.
- (void)toggleNavBar:(UITapGestureRecognizer *)gesture {
BOOL barsHidden = self.navigationController.navigationBar.hidden;
[self.navigationController setNavigationBarHidden:!barsHidden animated:YES];
}
If there is no navigation controller, link the navigation bar with an IBOutlet and replace with
- (void)toggleNavBar:(UITapGestureRecognizer *)gesture {
BOOL barsHidden = self.navBar.hidden;
self.navBar.hidden = !barsHidden;
}
Then add the following in the method -(void)viewDidLoad {}
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(toggleNavBar:)];
[self.view addGestureRecognizer:gesture];
[gesture release];
If the view where you are going to tap is a UIWebViewController, you have to add the protocol to the view controller and set it as delegate gesture.delegate = self; then add the following:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
This is needed because the UIWebViewController already implements its own gesture recognizers.
Ultimately, you want to send the -setHidden: message to your navigation bar. The easiest way to do this is to make an Outlet and an Action in your in your view controller. Then, in your .xib file, connect the navigation bar to the outlet and some button (even a large, full screen one) to the action.
Outlets and Actions are basic techniques used over and over in iOS
(and Mac) programming, so if you don't understand them, best go read
up on them now. Every beginning iOS/Mac programming book covers this
topic as does Apple's own Getting Started guide (pay particular
attention to the Configuring the View section).
Inside your action, send a message to the outlet like so:
-(void)myButtonAction:(id)sender{
[[self myNavigationBarOutlet] setHidden:YES];
}
This will hide the navigation bar whenever your button is tapped.
(This assumes you have a UINavigationBar in your .xib like you say. These directions will be different if you're working with a UINavigationController that manages its own UINavigationBar)

Resources