implementing textViewDidChange: - ios

So, I have this very simple list project with objective-c, where every item on the list should have a title and a description. When clicking on one of the items, the detail view of the item shows up. The title, on the navigation bar is the item's title, and the rest of the view is the item's description. By clicking on the title, the user should be able to change it, and by clicking on the description they should also be able to change it.
Up until changing the title everything is going OK, I've managed to do that. The problem is when it comes to changing the description. I tried using the delegate, but I guess I must be using some command wrong, because it's simply not working. I tried looking for it online, but all I find are solutions for the TextField, which doesn't really help me, since I want to display a possibly multiline description, and I would rather not have to change from a TextView to a TextField every time the user wants to edit it. So if anyone could help me out with that, that would be awesome.
Here is the code where I try using the delegate.
on viewDidLoad I have this:
[self.descriptionLabel setDelegate:self.descriptionLabel.delegate];
and then I have this, where it should perform the actions after the text is changed:
- (void)textViewDidChange:(UITextView *)textView {
NSLog(#"Hello World");
}
P.S.: I was also looking for a way to have the "Done" button show up over the keyboard, because as of now, once the keyboard is brought up, the only way to get it down again is going back to the table view and then into the detail view again. I tried a couple of things already, but I'll admit that I wasn't too thorough on my research. So, as a side note, if you could show that too, it would be great, otherwise, the one thing I'm really after here is the question above. Thanks for any help! :]

Summary of answer based on the comments.
The line:
[self.descriptionLabel setDelegate:self.descriptionLabel.delegate];
needs to be:
self.descriptionLabel.delegate = self;
You want the view controller to be the delegate since the view controller implements the text view delegate methods.
You also need to indicate that the view controller conforms to the UITextViewDelegate protocol.
In your .m file, add the following:
#interface DetailViewController () <UITextViewDelegate>
#end

Related

Which control should I use to display an ActionSheet-like view at the top of the screen?

I was asked to display a list of three options for the user in a View sliding from the top to bottom. They say it should slide from the top because the action is initiated from a dropdown-like button on the navigation bar.
Most of what I found on that subject mentions the deprecated UIActionSheet class.
The "new" way using UIAlertController doesn't seem to allow us to change position of the view. At the least from what I've found.
The end result I'm trying to get can be seen on the image below,
From what I've learned about iOS programming, one method I could think to achieve that would be to create a new UIViewController and to use a custom class to control the transition. But it just seems so much. And I think it wouldn't not look like a dropdown afterall.
The other option would be to create the TableView with options and leave it on the Controller where it should be displayed, configuring its height to zero. And then Animating when necessary. I also have such a bad feeling doing it this way.
Is there a right way to do this on iOS? Does one of the options I've found seems acceptable?
Thanks.
Following the suggestion given by #Losiowaty on the comments, I started looking for a custom View/Control on cocoapods and ended up finding quite a few that did what I was looking.
The one I decided to use is this:
https://github.com/lminhtm/LMDropdownView

TableView didSelectRowAtIndexPath not called

So I have added a UIUITableView to a UIViewController. I can't use a UITableViewController for reasons I don't need to explain since it will be unnecessary information. Anyway, I have set the delegate, and the data source to this viewController. I've added the delegate and datasource protocols as well. The cells are populated correctly, so the datasource is working fine. I can also scroll so it all works fine.
However, I can't get the didSelectRowAtIndexPath to trigger. It SHOULD trigger, but doesn't. I've read and a lot of issues with this can be correlated to a UIGestureRecognizer, but I haven't implemented one. I also use the standard UITableView, so not a custom made one.
If I long press the cells (3-4 sec) then it gets triggered as it's supposed to. This suggests that there is some issue with another view or something absorbing the tap gesture, which I have no control over. How would I solve this?
No, it's not didDeselectRowAtIndexPath.
Yes all delegates and datasources are correct, since I can get the delegates/sources to trigger.
Yes, Single Selection is set on the TableView in the inspector.
Yes, everything has user interaction enabled.
If I just copy the code over to a UITableViewController it will work just fine, but right now that is not an option, I'm afraid. Anyone got any ideas on how to solve this? Most people who've had this issue has either had the issues in the list above, or added a UIGesture on top of the UITableView - I haven't.
I want to start by saying that I appreciate all the answers here provided, it gave me a lot of things to try out so I learned a lot - thanks! None of your suggestions worked, but simply because I'm a complete idiot. I said in the post that I did NOT implement a UIGestureRecognizerwhich I didn't...in that class, but in its super class. So I DID in fact implement it, but in a class that this ViewController was a subclass off. The only reason I didn't remember it was because I haven't looked at that super class for weeks.
Someone did suggest it in the comments that I should check for it, and I did and I was already certain I didn't implement one, so I quickly dismissed it. But now, after about 4 hours of debugging and recreating the project, adding things one by one, I eventually realized that the only thing that differed at this point was the Super Class, and the first piece of code I see when I open the file up was a GestureRecognizer...
So keep this in mind in the future everyone - I know I will. Thanks again for the help!
Sincerely,
The complete idiot.
Make sure you don't add any controller in that cell, which covers the entire cell and also the user interaction of that controller is enabled.
Due to that controller's user interaction enabled the tap action is taken by that controller and when you long press that cell, that cell will receive your tap.
Example :
UIView *_view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _cellWidth, _cellHeight)];
[_view setUserInteractionEnabled:YES];
[cell.contentView addSubview:_view];
In the above case that view got your tap instated of the cell.

How to make IBAction (from button pressed on View1) finish BEFORE View2 viewDidLoad happens?

I'm asking this because I haven't found answer or solution on any other topic, sorry if this question was already asked and answered. THIS didn't answer my question, although problem is similar.
I am trying to explain it as possibly good as I can.
I'm having a singleton containing data used in application, let's call it DataStore. I'm trying to change some value in it, let's say DataStore.x, using one of IBActions (by pressing one of multiple buttons in View1). This button is also responsible for changing view to View2, modal link. viewDidLoad function from View2 is using DataStore.x variable.
Problem :
DataStore.x isn't set by IBAction yet when it's being used by viewDidLoad (using NSLog gave me information that value is being set, but too late).
prepareForSegue function would be perfect if I knew inside it which button was pressed, so before I switch views I can put the proper value to DataStore.x.
Thank you for your time.
Karol

clearButton not working in UITextEditField

This is one of those "it was working a while ago" troubleshooting efforts.
I'm working on the document preview view controller, in which is a scroll view, which itself contains subclasses of UIView that represent each document. I'm modeling this pretty closely to how Keynote handles its document preview, except I build my scroll view horizontally and with paging. But the standard user experience is present: Long press on a document icon causes all document icons to start jiggling, nab bar has + button and Edit button, etc.
The issue at hand is that when you tap on the name of a document, I hide all the others, move the one being edited front and center, build a new text edit field, add it as a subview atop the real name label, and set it as first responder; but the
[editNameTextField setClearButtonMode:UITextFieldViewModeWhileEditing];
while correctly showing in the edit field is not taking any action when the user taps on the clear button.
I can't figure out what I may have done to cause this to not work -- it had been!
My first thought was that somehow my instance of this subclass is no longer the delegate for this text edit field. To try and confirm/deny that, I usurped a tap on the image view of the document preview to compare the delegate property to self, and it passes.
if (editNameTextField) {
NSLog(#"editNameTextField is still active");
if ([editNameTextField.delegate isEqual:self]) {
NSLog(#"we're still the delegate for the editNameTextField");
}
}
Editing the text within the edit field works fine. Pressing the Return/Done key correctly sends the delegate message textFieldShouldReturn:
While investigating this I implemented the delegate method textFieldShouldClear: just to write a log message if the method gets called (and return YES of course). It never gets called.
My next thought was that perhaps a subview had covered up the area where the clear button sits. So I implemented textFieldShouldBeginEditing: and used the opportunity to bring my the text field to the front. That didn't change anything either. I set a debugger breakpoint there to play a sound when it was called, and it got called, so I know my text edit field is frontmost.
I have only one troubleshooting strategy remaining: Go backwards through snap shots until it starts working again. Before doing that I thought I'd see if any of the more experienced folks out here have any suggestions of what to try next.
Where are you adding the textfield? As a subview of the scrollView? If you added the textfield and it is out of bounds of its parent view it won't receive any touches.
You can try and not call becomeFirstResponder and see if clicking it will show keyboard. Another possible error might be that the parent view of the UITextField has userInteractionEnabled = NO.
Without seeing more code I'm afraid I can not offer more solutions.

How to increment a selected table row on iPhone

If someone was able to help me with the following, that would be great!
So here is what I'm trying to do. My app is basically a rss reader. The topics of the rss entries are displayed in a table view. Tapping on an entry opens a web view which displays the whole story. To this web view I have added a toolbar with up and down arrows so the user would be able to jump to the next/previous story without leaving the web view and having to tap another entry in the table. My problem is that I have no idea how to archieve this. Maybe this is related to the structure of my app. My guess is that I have to somehow increment the selected row on tapping the button.
As I said, maybe the code is a bit complicated, so I've posted the whole project here: http://www.schimanke.com/flo.zip It would be great if someone could have a look and tell me what to do.
What you need is to know which row is currently selected on your model. Since you have a reference to the model from your webview, that's easy:
int row = [mainModel.blogEntries indexOfObject:mainModel.selectedBlogEntry];
So all you need after that is to show the next (or previous) entry. Based on your code, it goes like this:
- (void) showNextPrevEntry:(int)increment usingTheOldController:(BlogEntryController *)controller {
int row = [mainModel.blogEntries indexOfObject:mainModel.selectedBlogEntry];
if (row+increment<[mainModel.blogEntries count] && row+increment>=0) {
mainModel.selectedBlogEntry = [ mainModel.blogEntries objectAtIndex:row+increment];
controller.mainModel = mainModel;
[controller viewDidLoad];
}
}
I don't think it's healthy to call viewDidLoad. Maybe you need another method just for updating the current loaded view and call that from your viewDidLoad. Also I'm not sure why you are using notifications for handling the button presses from the toolbar, but it works. :)

Resources