UA-17470720-3

Jump to content


Photo
- - - - -

Searching a detailModel


  • Please log in to reply
10 replies to this topic

#1 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 521 posts
  • LocationIreland
Reputation: 133
Popular

Posted 26 May 2015 - 07:34 AM

Hi all,

 

I'm trying to implement the searching of a detailView, I have Setlist > Songs > Notes and I'm trying to search through all the Songs in a Setlist to find one Song.

 

Tarek explained here http://sensiblecocoa...ion/#entry11570 about changing from a regular SCTableViewModel to a  SCArrayOfObjectsModel and then setting to TRUE enableSearchController of that SCArrayOfObjectsModel and volia, searching.

 

Sounded simple. But I'm not getting it to work at all. Here's my stripped back code:

 

 



-(void)viewDidLoad {
    [super viewDidLoad];

    self.navigationBarType = SCNavigationBarTypeEditRight;

    self.managedObjectContext = [(id)[UIApplication sharedApplication].delegate managedObjectContext];


#pragma mark - NoteEntity

    SCEntityDefinition *noteEntityDefinition = [SCEntityDefinition definitionWithEntityName:@"NoteEntity"
                                                                       managedObjectContext:self.managedObjectContext
                                                                        propertyNamesString:@"noteText"
                                                ];
    noteEntityDefinition.requireEditingModeToEditPropertyValues = NO;
    noteEntityDefinition.orderAttributeName = @"noteOrder";

    SCPropertyDefinition *noteTextPropertyDefinition = [noteEntityDefinition propertyDefinitionWithName:@"noteText"];
    noteTextPropertyDefinition.title = nil;
    noteTextPropertyDefinition.type = SCPropertyTypeTextView;
    noteTextPropertyDefinition.existsInCreationMode = YES;
    noteTextPropertyDefinition.existsInEditingMode = YES;
    noteTextPropertyDefinition.existsInNormalMode = YES;
    noteTextPropertyDefinition.existsInDetailMode = YES;
    noteTextPropertyDefinition.required = YES;

#pragma mark - SongEntity


    SCEntityDefinition *songEntityDefinition = [SCEntityDefinition definitionWithEntityName:@"SongEntity"
                                                                       managedObjectContext:self.managedObjectContext
                                                                        propertyNamesString:@":(songName);:(songNotes);"
                                                ];
    songEntityDefinition.requireEditingModeToEditPropertyValues = YES;
    songEntityDefinition.orderAttributeName = @"songOrder";

    SCPropertyDefinition *songNamePropertyDefinition = [songEntityDefinition propertyDefinitionWithName:@"songName"];
    songNamePropertyDefinition.existsInCreationMode = YES;
    songNamePropertyDefinition.existsInEditingMode = YES;
    songNamePropertyDefinition.existsInNormalMode = NO;
    songNamePropertyDefinition.existsInDetailMode = YES;
    songNamePropertyDefinition.required = YES;


    SCPropertyDefinition *notesPropertyDefinition = [songEntityDefinition propertyDefinitionWithName:@"songNotes"];
    notesPropertyDefinition.existsInCreationMode = NO;
    notesPropertyDefinition.existsInEditingMode = YES;
    notesPropertyDefinition.existsInNormalMode = NO;
    notesPropertyDefinition.existsInDetailMode = YES;
    notesPropertyDefinition.required = YES;

    SCArrayOfObjectsAttributes *notesArrayOfObjectsAttributes = [SCArrayOfObjectsAttributes attributesWithObjectDefinition:noteEntityDefinition
                                                                                                          allowAddingItems:YES
                                                                                                        allowDeletingItems:YES
                                                                                                          allowMovingItems:YES
                                                                                                expandContentInCurrentView:YES
                                                                                                      placeholderuiElement:nil
                                                                                                     addNewObjectuiElement:[SCTableViewCell cellWithText:@"New Note…" textAlignment:NSTextAlignmentLeft]
                                                                                   addNewObjectuiElementExistsInNormalMode:NO
                                                                                  addNewObjectuiElementExistsInEditingMode:YES
                                                                 ];

    notesArrayOfObjectsAttributes.sectionActions.cellForRowAtIndexPath = ^SCCustomCell*(SCArrayOfItemsSection *itemsSection, NSIndexPath *indexPath) {
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:nil nibName:@"NoteCell"];
        return customCell;
    };

    notesPropertyDefinition.attributes = notesArrayOfObjectsAttributes;


#pragma mark - SetlistEntity


    SCEntityDefinition *setlistEntityDefinition = [SCEntityDefinition definitionWithEntityName:@"SetlistEntity"
                                                                          managedObjectContext:self.managedObjectContext
                                                                           propertyNamesString:@":(setlistName);:(setlistSongs);"
                                                   ];
    setlistEntityDefinition.orderAttributeName = @"setlistOrder";
    setlistEntityDefinition.requireEditingModeToEditPropertyValues = YES;

    SCPropertyDefinition *setlistNamePropertyDefinition = [setlistEntityDefinition propertyDefinitionWithName:@"setlistName"];
    setlistNamePropertyDefinition.required = YES;
    setlistNamePropertyDefinition.existsInCreationMode = YES;
    setlistNamePropertyDefinition.existsInEditingMode = YES;
    setlistNamePropertyDefinition.existsInNormalMode = NO;
    setlistNamePropertyDefinition.existsInDetailMode = YES;

    SCPropertyDefinition *songsPropertyDefinition = [setlistEntityDefinition propertyDefinitionWithName:@"setlistSongs"];
    songsPropertyDefinition.existsInCreationMode = NO;
    songsPropertyDefinition.existsInEditingMode = YES;
    songsPropertyDefinition.existsInNormalMode = YES;
    songsPropertyDefinition.existsInDetailMode = YES;
    SCArrayOfObjectsAttributes *songsArrayOfObjectsAttributes = [SCArrayOfObjectsAttributes attributesWithObjectDefinition:songEntityDefinition
                                                                                                          allowAddingItems:YES
                                                                                                        allowDeletingItems:YES
                                                                                                          allowMovingItems:YES
                                                                                                expandContentInCurrentView:YES
                                                                                                      placeholderuiElement:nil
                                                                                                     addNewObjectuiElement:[SCTableViewCell cellWithText:@"New Song…" textAlignment:NSTextAlignmentLeft]
                                                                                   addNewObjectuiElementExistsInNormalMode:NO
                                                                                  addNewObjectuiElementExistsInEditingMode:YES
                                                                 ];

    songsArrayOfObjectsAttributes.sectionActions.cellForRowAtIndexPath = ^SCCustomCell*(SCArrayOfItemsSection *itemsSection, NSIndexPath *indexPath) {
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:nil nibName:@"SongCell"];
        return customCell;
    };


    songsPropertyDefinition.attributes = songsArrayOfObjectsAttributes;

#pragma mark - Setlist Section

    SCArrayOfObjectsSection *setlistsSection = [SCArrayOfObjectsSection sectionWithHeaderTitle:nil entityDefinition:setlistEntityDefinition];
    setlistsSection.addNewItemCell = [SCTableViewCell cellWithText:@"New Setlist…" textAlignment:NSTextAlignmentLeft];
    setlistsSection.addNewItemCellExistsInEditingMode = YES;
    setlistsSection.addNewItemCellExistsInNormalMode = NO;
    setlistsSection.allowAddingItems = YES;
    setlistsSection.allowDeletingItems = YES;
    setlistsSection.allowMovingItems = YES;
    setlistsSection.allowEditDetailView = YES;
    setlistsSection.allowRowSelection = YES;
    setlistsSection.autoSelectNewItemCell = YES;
    setlistsSection.skipNewItemDetailView = NO;

    setlistsSection.sectionActions.cellForRowAtIndexPath = ^SCCustomCell*(SCArrayOfItemsSection *itemsSection, NSIndexPath *indexPath) {
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:nil nibName:@"SetlistCell"];
        return customCell;
    };

    setlistsSection.sectionActions.detailModelWillPresent = ^(SCTableViewSection *section, SCTableViewModel *detailModel, NSIndexPath *indexPath) {
        if (indexPath.row != NSNotFound) {

            [detailModel logProperties];

        }
    };

    [self.tableViewModel addSection:setlistsSection];
}

 

So that all works as expected. In my detailModelWillPresent the model is a bog standard SCTableViewModel.

 

 

If I add in this:

 
  setlistsSection.sectionActions.detailTableViewModelForRowAtIndexPath = ^SCTableViewModel*(SCTableViewSection *section, NSIndexPath *indexPath) {
        if (indexPath.row == NSNotFound) {
            return nil;
        }
        else {
            SetlistEntity *setlist = (SetlistEntity *)[section cellAtIndex:indexPath.row].boundObject;
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"songSetlist == %@",setlist];
            SCArrayOfObjectsModel *arrayOfObjectsModel = [[SCArrayOfObjectsModel alloc] initWithTableView:nil entityDefinition:songEntityDefinition filterPredicate:predicate];
            arrayOfObjectsModel.enableSearchController = YES;
            arrayOfObjectsModel.searchPropertyName = @"songName";

            return arrayOfObjectsModel;
        }
    };

 

 

The model is now indeed a SCArrayOfObjectsModel, and I still get all my Songs in a list, but no search bar. And I now can't re-order the Songs, and I've lost the cell to edit the setlistName.

 

 

Very confused!

 

I'm obviously missing something basic here.

 

Any pointers very much appreciated.

 

 

 


Cheers,

Dave

www.dgapps.ie

#2 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 571 posts
  • LocationThe Grid
Reputation: 145
Popular

Posted 26 May 2015 - 12:09 PM

Greetings Program!
 

I'm missing something too; I just tried adding it to my cellAction.detailTableViewModel and I didn't see it either:

 

pointsDef.cellActions.detailTableViewModel = {
    (cell, indexPath)->SCTableViewModel in
    
    var detailObjectsModel = SCArrayOfObjectsModel()
    detailObjectsModel.enableSearchController = true

    return detailObjectsModel
}

 

I also tried it where I'm creating a new SCArrayOfObjectsModel to push and I didn't get a search bar there either, as well, the sectionHeaderTitleForItem no longer fired:

 

let tableViewModel = SCArrayOfObjectsModel(tableView: viewController.tableView, entityDefinition:pointDef)
tableViewModel.enableSearchController = true

// This does not fire when enableSearchController is set to true
tableViewModel.modelActions.sectionHeaderTitleForItem = {
    (itemsModel, item, itemIndex)->String! in
}

 

Wg


Edited by wizgod, 26 May 2015 - 12:19 PM.

P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#3 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 26 May 2015 - 12:40 PM

Hey guys,

 

The whole problem you're having here is an architectural one, where 'enableSearchController' needs to have an existing table view when called, while you're calling it in the 'detailTableViewModel' action where no detail table view exists yet. This is probably our bad and we should reconsider the architecture here. For the time being, you can simply set enableSearchController in 'detailModelWillPresent' instead. The following code does the trick for our bundled TasksApp sample (notice that I am using cellActions and *not* sectionActions, since taskSteps is an SCArrayOfObjectsCell):

 

// MasterViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    SCDataDefinition *taskDef = [self dataDefinitionWithIBName:@"Task"];
    SCPropertyDefinition *taskStepsPDef = [taskDef propertyDefinitionWithName:@"taskSteps"];
    
    taskStepsPDef.cellActions.detailTableViewModel = ^SCTableViewModel*(SCTableViewCell *cell, NSIndexPath *indexPath)
    {
        SCArrayOfObjectsModel *detailModel = [SCArrayOfObjectsModel modelWithTableView:nil];
        
        return detailModel;
    };
    taskStepsPDef.cellActions.detailModelWillPresent = ^(SCTableViewCell *cell, NSIndexPath *indexPath, SCTableViewModel *detailModel)
    {
        if([detailModel isKindOfClass:[SCArrayOfObjectsModel class]])
            [(SCArrayOfObjectsModel *)detailModel setEnableSearchController:YES];
    };
}

 

Hope this helps.



#4 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 571 posts
  • LocationThe Grid
Reputation: 145
Popular

Posted 26 May 2015 - 02:13 PM

For the tableViewModel I was pushing, I had to add it to the viewController.actions.willAppear.

viewController.actions.willAppear = {
    (viewController: SCTableViewController!) in

    viewController.canDisplayBannerAds = true
    
    let photoCell = SCCustomCell(text: nil, objectBindingsString: nil, nibName: "Photo")
    photoCell.boundObject = cell.boundObject
    
    photoCell.displayImage()
    
    viewController.tableViewModel.tableView.tableHeaderView = photoCell.contentView
    
    if viewController.tableViewModel.isKindOfClass(SCArrayOfObjectsModel) {
        (viewController.tableViewModel as! SCArrayOfObjectsModel).enableSearchController = true
        (viewController.tableViewModel as! SCArrayOfObjectsModel).searchPropertyName = "activity.name"
    }
}

 

Some behaviour I've noticed:

 

Unfortunately, enabling the search controller replaces my custom header, LOL! No biggie right now; was testing to see if the search worked.

 

Also, I have a custom button cell which ends up moving up in front of the section header when the search bar is tapped. When you exit search and reenter it, the custom button disappears but reappears when you exit out of search :D .

 

The custom button does not have a boundObject so STV is giving this error warning and the search returns no results; probably because it threw the warning.

**STV** Warning: Invalid search predicate: activity.name CONTAINS[cd] "B".

If I remove the custom cell, it works fine and if I bind it to an object with the property, no doubt it will work.

 

Wg


P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#5 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 521 posts
  • LocationIreland
Reputation: 133
Popular

Posted 27 May 2015 - 04:05 AM

Hi Tarek and wizgod,

 

Thanks for the replies. I was able to enable Search in the example TasksApp using Tarek's code above, and in the CoreDataApp as well once I changed the dataDefinitionWithIBName: to TaskEntity. Great!

 

The objects I want to search through are expandContentInCurrentView:YES and I think that's where I am having problems. Enabling that in the CoreDataApp and there's no search. It's more than likely that I'm missing something basic again.

 

 

So is there a way to enable search on a section that is expandContentInCurrentView:YES? In my main app there are 6 (!) sections total, one of which is the Songs section, but only the Songs section is shown normally, the other 5 appear in Edit mode. But I'd want to be able to search the Song section in both normal and Edit mode.

 

I'm thinking I might need to do it via a button that pushes the search view, and then selecting a Song from that search view dismisses the search view and scrolls the table containing the Songs section to show the selected Song. Unless there's another way to do it?


Cheers,

Dave

www.dgapps.ie

#6 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 571 posts
  • LocationThe Grid
Reputation: 145
Popular

Posted 27 May 2015 - 07:20 AM

I thought I'd play around and see what happens when I set it for the detail view (in the TasksApp):

 

self.tableViewModel.sectionActions.detailTableViewModelForRowAtIndexPath = ^SCTableViewModel*(SCTableViewSection *section, NSIndexPath *indexPath)
{
    SCArrayOfObjectsModel *detailModel = [SCArrayOfObjectsModel modelWithTableView:nil];
    
    return detailModel;
};

self.tableViewModel.sectionActions.detailModelWillPresent = ^(SCTableViewSection *section, SCTableViewModel *detailModel, NSIndexPath *indexPath)
{
    if([detailModel isKindOfClass:[SCArrayOfObjectsModel class]])
        [(SCArrayOfObjectsModel *)detailModel setEnableSearchController:YES];
};

 

Nothing happened because sectionActions.detailTableViewModelForRowAtIndexPath didn't fire. I used this action because cellActions.detailTableViewModel will not fire for self.tableViewModel.

 

However, in my swift app, I did the following and it did fire and the detailView showed the search bar but the tableView was empty (because of setting it as an SCArrayOfObjectsModel).

 

tableViewModel.sectionActions.detailTableViewModelForRowAtIndexPath = {
    (section, indexPath)->SCTableViewModel in
    
    var detailObjectsModel = SCArrayOfObjectsModel()
    
    return detailObjectsModel
}

 

I'm hoping I missed something too but I think, in this case, you'll need to add the search bar and do the filtering yourself... Unless Tarek can pull a rabbit out of his hat :D.

 

Wg


P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#7 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 27 May 2015 - 08:15 AM

@dave: Search uses a search controller, which takes over the whole table view. It's because of that that it's very much recommended that whatever you're searching be in its own table view, and not in a separate section. STV supports this by providing automatic search via the SCArrayOfObjectsModel (and not section). If you still need this custom searching behavior, then one idea might be adding an extra cell with a search bar at the top of the section, then filtering manually when the user types. Again, I am not a really big fan of this (nor is Apple I believe).

 

@Wg: Re custom header: Yes, Apple recommends placing the search bar in the table view's header, but you could always provide your own custom UISearchBar and set it to SCArrayOfObjectsModel's searchBar property. Again, probably every single Apple sample with search has the search bar in the table's header by default. 


Edited by Tarek, 27 May 2015 - 08:17 AM.


#8 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 521 posts
  • LocationIreland
Reputation: 133
Popular

Posted 27 May 2015 - 08:30 AM

Hi Tarek,

 

Yes, understood.

 

I'm going to try doing search via a button that pushes the STV search view, and then selecting a Song from that search view will dismisses the search view and scroll the main table containing the Songs section to show the selected Song.

 

I think that will work, and not break any Apple conventions...


Cheers,

Dave

www.dgapps.ie

#9 wizgod

wizgod

    I'm what you guys call a User

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 571 posts
  • LocationThe Grid
Reputation: 145
Popular

Posted 27 May 2015 - 11:59 AM

Ok, so here's what I did to get this working without having to push out a separate search view:

 

tableViewModel.sectionActions.detailModelWillPresent = {
    (section, detailModel, indexPath) in
    
    let activeCell = section.ownerTableViewModel.cellAtIndexPath(indexPath) as SCTableViewCell!
    if activeCell == nil || activeCell.boundObject == nil
    {
        detailModel.viewController.title = "Add New Profile"
        (detailModel.viewController as! SCTableViewController).navigationBarType = SCNavigationBarType.DoneRightCancelLeft

        return
    }
    
    // Add the search bar to the header here; we don't want to add it if this is the "add new" detail view.
    var searchBar = UISearchBar(frame: CGRectMake(0, 0, detailModel.tableView.frame.width, 64))
    
    // Strong reference, [weak self] won't work; not sure if you can (how to) set the delegate to STV's. 
    searchBar.delegate = self

    detailModel.tableView.tableHeaderView = searchBar
}

 

Then added the delegate method:

 

func searchBar(searchBar: UISearchBar, textDidChange searchText: String)
{
    println("searchText: \(searchText)")
    
    var predicate = NSPredicate(format: "objectiveTitle contains[cd] %@", searchText)
    // The index of my expandedContentSection is 3; put yours in there :-)
    (tableViewModel.activeDetailModel.sectionAtIndex(3) as! SCArrayOfItemsSection).dataFetchOptions = SCDataFetchOptions(sortKey: "objectiveTitle", sortAscending: false, filterPredicate: searchText == "" ? nil : predicate)
    
    tableViewModel.activeDetailModel.reloadBoundValues()
    tableViewModel.activeDetailModel.tableView.reloadData()
}


You can also filter in objectiveDef.attributes.expandedContentSectionActions.didFetchItemsFromStore and remove the predicate and dataFetchOptions from the search bar delegate method, leaving only the tableView/model reloads.

 

objectivesDef.attributes.expandedContentSectionActions.didFetchItemsFromStore = {
    (itemsSection, items) in

    if itemsSection.ownerTableViewModel.tableView != nil {
        if let searchBar = itemsSection.ownerTableViewModel.tableView.tableHeaderView as? UISearchBar
        {
            println("searchText: \(searchBar.text)")
            var predicate = NSPredicate(format: "objectiveTitle contains[cd] %@", searchBar.text)
            
            var dataFetchOptions = SCDataFetchOptions(sortKey: "objectiveTitle", sortAscending: false, filterPredicate: searchBar.text == "" ? nil : predicate)
            dataFetchOptions.filterMutableArray(items)
            dataFetchOptions.sortMutableArray(items)
        }
    }
}

 

func searchBar(searchBar: UISearchBar, textDidChange searchText: String)
{
    println("searchText: \(searchText)")

    tableViewModel.activeDetailModel.reloadBoundValues()
    tableViewModel.activeDetailModel.tableView.reloadData()
}

 

I think there's less code if you put it in the searchBar delegate method but more freedom/control in .didFetchItemsFromStore to do other things to the data...

 

You could essentially add the sorting/filtering to other expandedContentSections' didFetchItemsFromStore (or set the dataFetchOptions for the other expandedContentSections in the searchBar delegate) if you wanted to be able to search multiple expandedContentSections :D.

 

Wg


Edited by wizgod, 29 May 2015 - 12:40 PM.

  • Tarek likes this

P.S. I love Swift... talk Swift.. Never too old school to learn yet another programming language. LOL! ;-)


#10 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 521 posts
  • LocationIreland
Reputation: 133
Popular

Posted 29 May 2015 - 07:08 AM

I tried it using a search button pushing a STV searchView, but I wasn't 100% with the way it all worked from a user point of view so I ended up doing as per Wizgod's first example above, just in Objective C :-) Thanks for the example Wizgod!

 

Here's my additions to my original code:

 


    songsArrayOfObjectsAttributes.sectionActions.cellForRowAtIndexPath = ^SCCustomCell*(SCArrayOfItemsSection *itemsSection, NSIndexPath *indexPath) {
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:nil nibName:@"SongCell"];

        customCell.cellActions.didSelect = ^(SCTableViewCell *cell, NSIndexPath *didSelectIndexPath) {


            BOOL searchBarWasFirstResponder = NO;
            if ([weakSelf.songSearchBar isFirstResponder]) {
                [weakSelf finishedWithSearchBar];
                searchBarWasFirstResponder = YES;
            }


            SongEntity *song = (SongEntity *)cell.boundObject;
            NSIndexPath *selectedIndexPath = [NSIndexPath indexPathForRow:[song.songOrder integerValue] inSection:indexPath.section];

            if (![itemsSection.ownerTableViewModel.tableView isEditing]) {
                // Normal mode: selected and selected from search results
                // Standard STV dispatch event
                [itemsSection dispatchEventSelectRowAtIndexPath:selectedIndexPath];
            }
            else if (searchBarWasFirstResponder){
                // Edit mode: selected from search results.
                // Scroll to the selected cell and highlight it so the user can see it
                [cell.ownerTableViewModel.tableView scrollToRowAtIndexPath:selectedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [[cell.ownerTableViewModel.tableView cellForRowAtIndexPath:selectedIndexPath] setHighlighted:YES animated:YES];

                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        [[cell.ownerTableViewModel.tableView cellForRowAtIndexPath:selectedIndexPath] setHighlighted:NO animated:YES];
                    });
                });
            }
            else {
                // Edit mode: selected
                // No drill down in Edit mode
            }
        };

        customCell.cellActions.didLayoutSubviews = ^(SCTableViewCell *cell, NSIndexPath *didLayoutSubviewsIndexPath) {
            /*
             If the estimatedRowHeight does not equal the actual row height
             then scrollToRowAtIndexPath: gets it wrong! This is a known bug in 
             iOS 8.3 http://www.openradar.me/20829131
             */
            itemsSection.ownerTableViewModel.tableView.estimatedRowHeight = cell.height;
        };

        return customCell;
    };

 

And then also:

 

 


#pragma mark - SearchBar Methods


-(void)finishedWithSearchBar {
    [self.songSearchBar resignFirstResponder];
    [self.songSearchBar setShowsCancelButton:NO animated:YES];
    self.songSearchBar.text = nil;

    SCArrayOfObjectsSection *arrayOfObjectsSection  = (SCArrayOfObjectsSection*)[self.songsArrayOfObjectsModel sectionAtIndex:kdgSongsSectionIndex];
    [arrayOfObjectsSection.dataFetchOptions logProperties];

    if (arrayOfObjectsSection.dataFetchOptions) {
        arrayOfObjectsSection.dataFetchOptions = nil;
        //[self.tableViewModel.activeDetailModel reloadBoundValues]; // doesn't seem to be required
        [self.songsArrayOfObjectsModel.tableView reloadData];
    }

    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

#pragma mark - UISearchBarDelegate Methods

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    [self.navigationController setNavigationBarHidden:YES animated:YES];
    [searchBar setShowsCancelButton:YES animated:YES];

    return YES;
}


- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"songName contains[cd] %@",searchText];
    SCArrayOfObjectsSection *arrayOfObjectsSection  = (SCArrayOfObjectsSection*)[self.songsArrayOfObjectsModel sectionAtIndex:kdgSongsSectionIndex];
    arrayOfObjectsSection.dataFetchOptions = [SCDataFetchOptions optionsWithSortKey:@"songOrder" sortAscending:YES filterPredicate:predicate];
    [self.songsArrayOfObjectsModel reloadBoundValues];
    [self.songsArrayOfObjectsModel.tableView reloadData];
}


- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
    [self finishedWithSearchBar];
    return YES;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self finishedWithSearchBar];
}


 

Great!!


  • Tarek likes this
Cheers,

Dave

www.dgapps.ie

#11 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 521 posts
  • LocationIreland
Reputation: 133
Popular

Posted 29 May 2015 - 07:10 AM

Ah, and this bit to add the search bar:

 


    setlistsSection.sectionActions.detailModelWillPresent = ^(SCTableViewSection *section, SCTableViewModel *detailModel, NSIndexPath *indexPath) {
        DGBLog(@"setlistsSection.sectionActions.detailModelWillPresent");
        if (indexPath.row != NSNotFound) {
            weakSelf.songsArrayOfObjectsModel  = (SCArrayOfObjectsModel *)detailModel;

            if (!weakSelf.songSearchBar) {
                weakSelf.songSearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
            }

            weakSelf.songSearchBar.delegate = self;
            weakSelf.songSearchBar.placeholder = @"Search Songs";
            weakSelf.songSearchBar.showsCancelButton = NO;
            weakSelf.songSearchBar.text = nil;

            detailModel.tableView.tableHeaderView = weakSelf.songSearchBar;
        }
    };


Cheers,

Dave

www.dgapps.ie




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users