jeudi 30 avril 2015

Add completion for deleteRowAtIndexPaths with an extension or didEndDisplayingCell

I'd like to do something after deleteRowsAtIndexPaths has finished it's animation.

I can achieve this by wrapping it in animateWithDuration but it doesn't feel like the right way of doing it.

Another way is using didEndDisplayingCell but so far I can't figure how to use this method, even with apple's documents.

What I'm trying to do is:

  • Delete a cell by swiping it
  • Remove it from my data model
  • Delete the row with deleteRowsAtIndexPaths

After the row has been deleted and animation has ended:

  • Reload sections by calling reloadSections

The code I'm using:

func deleteObject(ojbectName: String) {
    let indexPath = // create indexPath

    // Delete the item in data model and table
    myData.removeAtIndex(index)
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Left)

    // Reload section after row animation has ended        
    let indexSet = NSIndexSet(indexesInRange: NSMakeRange(myData[indexPath.section].startIndex, myData[indexPath.section].endIndex))
    tableView.reloadSections(indexSet, withRowAnimation: .None)
}

I tried creating an extension for UITableView that didn't go well. Is there someone who can tell me how to create one or how to use didEndDisplayingCell so I can reload the section after the animation has ended?

See more ..

Swift / IOS - Auto resizing label with tableView.rowHeight = UITableViewAutomaticDimension

I have a table that displays a custom cell containing some user entered data. The length of this data varies and therefore I am implementing tableview.rowHeight = UITableViewAutomaticDimension.

This works fine, but I want the label to have an inset of 10x10x10x10. When I override the drawTextInRect on the custom label the insets are drawn and that works OK.

The problem is that the auto resizing doesn't seem to take into account the new insets and therefore truncates the label text and I can't figure out how to get around this.

By doing println() prior to drawing the rect and returning the cell I found that the cell is returned before the insets are drawn which would lead me to believe that I need to update the cell content somewhere to fix this?

CustomNoteLabel

class CustomNoteLabel: UILabel {
    override func drawTextInRect(rect: CGRect) {

    var insets:UIEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)

    println("Drawing insets")

    return super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))

    }

}

TableViewInit()

    self.tableView = UITableView()
    self.tableView.frame = CGRectMake(0, 200, self.view.frame.width, self.view.frame.height - 200)
    self.tableView.dataSource = self
    self.tableView.delegate = self
    self.tableView.backgroundColor = UIColor.whiteColor()
    self.tableView.scrollEnabled = true
    self.tableView.estimatedRowHeight = 200.0
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
    self.tableView.registerNib(UINib(nibName: "NoteTableViewCell", bundle: nil), forCellReuseIdentifier: "cell")
    self.view.addSubview(tableView)

Thanks peoples!

See more ..

My UIViewController "does not conform to protocol: 'UITableViewDataSource'"

So, first of all, I realize that there are many questions like this, and I've gone through at least 13 (I've been counting), but my error never seems to go away. I have some code in Swift for a UITableView that should list what is in an array. Sadly, I get the error that I wrote in the title: ... "does not conform to protocol: 'UITableViewDataSource'". Here is my code. Any idea why it doesn't work?

import Foundation
import UIKit
class history: UIViewController,UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var table: UITableView!
var items: [String] = ["One", "two", "three", "four", "five"]

func tableView(tableView: UITableView!, numberofRowsInSection section: Int)->Int{
    return items.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)->UITableViewCell {
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "acell")
    cell.textLabel!.text = items[indexPath.row]

    return cell
}

override func prefersStatusBarHidden() -> Bool {
    return true
}


}

Thanks a lot in advance.

See more ..

UITableViewHeaderFooterContentView, init with identifier only

I created a custom UITableViewHeaderFooterContentView, the TableView is created programmatically and added to a ViewController. In viewDidLoad the header is registered with:

tableView.registerClass(Header.self, forHeaderFooterViewReuseIdentifier: "header")

Then in viewForHeaderInSection I created a reusable instance of this custom header with:

let header = tableView.dequeueReusableHeaderFooterViewWithIdentifier("header") as! Header

But when I run the app, it crashes with the message:

fatal error: use of unimplemented initializer 'init(frame:)' for class 'Project.Header'

The way the header is created now will call init(frame:) and init(reuseIdentifier:).

Question:
How do I create this header with just using init(reuseIdentifier:)?

See more ..

Dynamic cell height follow its content inside

I have a static cell which contains only a UILabel on my TableViewController. I am able to update my label on viewDidLoad method using the code below,

myLabel.text = "A\nB\nC\nD..."

but the cell remain its height even on breaking lines, all the text can be seen, it just display over the cell. How can I let my TableViewCell's height follow my label to get larger, like force to layout again?

I tried update the value after the label changed but nothing's happen.

myCell.frame.size.height = 200  //if calculate myself

See more ..

Embedded TableView not displaying TableViewCell

I have a TableView within a ViewController and connected it the following way to the view controller:

@interface ChooseViewController : UIViewController <UITableViewDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tableView;

I am selecting the cell for the table view the following way:

SongTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SongTableViewCell" forIndexPath:indexPath];

I dragged SongTableViewCell into the tableView in storyboard by the way. I then added an imageView to SongTableViewCell and set the image.

The imageView in SongTableViewCell is not displaying in the app though. Do you see anything I did wrong?

Is it possibly because I setup tableView as an IBOutlet? SongTableViewCell *cell is called in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

*Note: I also control dragged tableView to the view controller it is in and selected delegate.

See more ..

Best approach for UICollectionView

I'm building an app where I really need to display a list like the one seen in the iOS calendar app. I need to create a collectionView where I can have cells that expand enough to cover their respective hours, like so:

enter image description here

I've tried various things, including this project at Github which I didn't understand how to use in another project

As well as this project I quickly made with a UITableViewController while exploring different methods:

enter image description here

But I'm not really getting where I want to. I need to have the design seen in the first picture and was wondering if anyone could point me in the right direction to achieve that?

Thank you so much for help!!

See more ..

Populating a UITableView cell iOS8

I'm having a hair pulling problem in a UITableView. I'm just trying to pick out a name field from an array. I must be doing something dumb, but I can't see it. Any ideas please..

NSMutableArray *localStop = [localArray objectAtIndex:indexPath.row];
NSLog(@"localStop: %@", localStop);


BOTH OF THESE RETURN NULL

cell.nameLabel.text = [[localArray objectAtIndex:indexPath.row] valueForKey:@"Name" ];

OR

cell.nameLabel.text = [localStop valueForKey:@"Name"];


    NSLog(@"localStop Name1: %@", cell.nameLabel.text);
    NSLog(@"localStop Name2: %@", [[localArray objectAtIndex:indexPath.row] valueForKey:@"Name"]);

HOWEVER THE LATTER SHOWS NULL IN THE CELL, BUT DISPLAYS CORRECTLY IN THE CONSOLE.

CONSOLE OUTPUT:

 localStop: {
    Lat = "38.928922";
    Lon = "-77.037531";
    Name = "MT PLEASANT ST NW + IRVING ST NW";
    Routes =     (
        42,
        43
    );
    StopID = 1002005;
}


localStop Name1: (null)
localStop Name2: MT PLEASANT ST NW + IRVING ST NW

See more ..

Cells are only deleted/added once leaving and returning

I don't think it's necessary to post my code for this issue. I am just looking for an explanation or probably one line of code to solve my problem. When I delete or add a cellForRowAtIndexPath within my app, it is both added or deleted to Parse, but does not appear in the app until segueing to a different screen and returning. I have tried moving my delete and add codes into ViewDidLoad and ViewWillAppear

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        var object: PFObject = self.items[indexPath.row] as PFObject
        let alert : UIAlertView = UIAlertView(title: "Item deleted from cart!", message: "", delegate: self, cancelButtonTitle: "Dismiss")
        alert.show()

        object.deleteInBackgroundWithBlock({ (succeed, error) -> Void in

            self.tableView.reloadData()

        })
    }
}

See more ..

iOS Mutable Array Thread Saftey with UISearchBar and UITableView

I have a UISearchBar that when text is entered, iOS queries an API. The results of that API are displayed in a UITableViewController.

Note that the TableViewController's variable autoCompleteResults is populated with the result of the API call as mentioned above. Please see the definition below of that variable:

let concurrentAutoComplete:dispatch_queue_t = dispatch_queue_create("rptr string", DISPATCH_QUEUE_CONCURRENT)

private var internalACR:[[String: String]] = [[String:String]]()
var autoCompleteResults:[[String: String]] {
    get {
        var copy: [[String:String]]! // = [[String: String]]()
        dispatch_sync(concurrentAutoComplete) {
            copy = self.internalACR
        }
        return copy
    }
    set {
        dispatch_sync(concurrentAutoComplete) {
            self.internalACR = newValue

            dispatch_async(dispatch_get_main_queue()) {
                self.tableView.reloadData()
            }
        }
    }
}

The problem that I am having is when a user types on a slow phone, there are multiple tableView.reloadData() calls being made. There are cases where tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) is being called late and autoCompleteResults has been updated multiple times already. So when code from inside cellForRowAtIndexPath is executed

let test = autoCompleteResults[indexPath.row]["some identifier]

I get a fatal error saying that the index is out of bounds. This is because indexPath.row may be 10, but since autoCompleteResults has been updated multiple times since cellForRowAtIndexPath has been called, autoCompelteResults now only contains a count of 6 (for example).

How can I use Grand Central Dispatch or some thread safe technique to prevent this issue in Swift 1.2?

Thank you in advance.

See more ..

Objective-c reload tableview from another viewcontroller

I am super confused.

I have 2 controllers, lets call them controller1 and controller2.

In controller1.m I have this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    NSString *object = self.objects[indexPath.row];
    cell.textLabel.text = [object description];
    return cell;
}

and in controller2.m I am trying to reload the tableview in controller1.m:

- (void)GetRequest
{

    NSArray *tableData = [dataSource.areaData GetPurchaseOrderItems:[NSString stringWithFormat:@"%@%@",areaPickerSelectionString,unitPickerSelectionString]];

    if(!purchaseOrder.objects){
        purchaseOrder.objects = [[NSMutableArray alloc]init];
    }

    for(int i = 0; i < [tableData count]; i++){
        [purchaseOrder.objects addObjectsFromArray:[tableData objectAtIndex:i]];
        NSLog(@"%@",[tableData objectAtIndex:i]);
    }
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [purchaseOrder.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

    NSLog(@"%@", purchaseOrder.objects);

    //[self.tableView reloadData];

}

I have tried the following:

controller1.h:

@property(nonatomic, retain) UITableView *tableView;

controller1.m:

@synthesize tableView;

controller2.h:

#import "controller1.h"

@interface controller2 ()
{


    controller1 *purchaseOrder;

}

- (void)viewDidLoad {
     purchaseOrder = [[controller1 alloc]init];
}

and then [purchaseOrder.tableView reloadData];

and my tableView doesnt get reloaded. WTF ? I have no idea what I am doing wrong here. I also get this warning on:

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

and here is the warning:

Local declaration of 'tableView' hides instance variable

See more ..

Can UITableView's scroll 'smoothly' when using various height Self Sizing Cells?

I have a UITableView with Custom UITableViewCell's. The Cell's can vary between 200.0 and 300.0 and height.

Now if you open Facebook, you'll notice the scrolling in the News Feed is awfully choppy. However, this is likely due to that various videos that are loaded on every cell, and that the time taken in cellForRowAtIndexPath is greater than 13.67ms (1s/60frames). Hence the choppy 'flicker'.

Quora on the other hand has cells that are varying heights, between probably 150.0 and 400.0+. It scrolls pretty smoothly however.

Now, when I scroll my tableView it's as though my screen is 'jumping'. I will scroll down, and every now and then (may every new cell dequeue but not quite), it's as if something higher up in the tableview got a few pixels shorter in height, and therefore the screen i'm currently viewing jumped up a few pixels. (This is not what's happening, I'm just trying to paint a picture of what it looks like).

Now I know it's not a time related issue. My cellForRowAtIndexMethod is nowhere near 13.67ms. It's always around 3ms, so that's not the issue.

2 questions...

1) Is this typically indicative of an auto layout issue?

2) Is there an accurate/semi-accurate way to calculate estiamtedRowHeight when you have such varied cell heights, or would having an accurate number here not fix this issue anyway? Just an idea.

See more ..

how to access segue in 'didSelectRowAtIndexPath' - Swift/IOS

I know how to pass data using segues from prepareForSegue function, but the thing i have a TableViewCell from which there are two possible segues to two different ViewControllers (let's just say A, B as of now). It was suggested here that it is best to connect the segues to View controller rather than the tableCell itself, which infact worked perfectly. But i want to pass information to the second View controller when the cell is clicked, So how to access segue that i connected to the Source ViewController.

Code:

Inside prepareForSegue

if segue.identifier == "showQuestionnaire"{
      if let indexPath = self.tableView.indexPathForSelectedRow() {
        let controller = (segue.destinationViewController as! UINavigationController).topViewController as! QuestionnaireController
        let patientQuestionnaire = patientQuestionnaires[indexPath.row] as! PatientQuestionnaire
        controller.selectedQuestionnaire = patientQuestionnaire
        self.performSegueWithIdentifier("showQuestionnaire", sender: self)
      }
    }

Again: This question is not regarding passing information through prepareForSegue

See more ..

UITableViewController add item via method

I am using a UISplitviewController and I am trying to add items to the table view.

right now I have two ways

  1. Create a button and add it:

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    self.navigationItem.rightBarButtonItem = addButton;
    
    

and this code runs when the button is clicked:

- (void)insertNewObject:(id)sender {
    if (!self.objects) {
        self.objects = [[NSMutableArray alloc] init];
    }
    [self.objects insertObject:[NSDate date] atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

and adds an item to the table view:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    NSString *object = self.objects[indexPath.row];
    cell.textLabel.text = [object description];
    return cell;
}

this way works.

This is what I am trying to do:

- (void)GetRequest
{

    if (!self.objects) {
        self.objects = [[NSMutableArray alloc] init];
    }
    [self.objects insertObject:[NSDate date] atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

}

but this does not update the table view. I added a breakpoint and when I use the button I added, it goes into the table view, with the method it does not and I am calling the method via [MasterController GetRequest];

What am I doing wrong ?

I am calling GetRequest from another controller.

This is how MasterController is getting defined:

@interface DetailController ()
{

    MasterController *MasterController;

}

See more ..

Table view frame showing up at unintended location

This is what my view controller looks like with these two table views. As you can see, the left looks like the frame is in the intended place and the right does not. I've posted my code and the origin y is in the same place in both. What could be causing this?

View Controller Image with two table views

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    CGFloat halfLength = self.view.frame.size.width / 2;
    CGRect ingredientsFrame = CGRectMake(0, 0, halfLength - 1, self.view.frame.size.height);
    CGRect modsFrame = CGRectMake(halfLength + 1, 0, halfLength - 1, self.view.frame.size.height);

    _ingredientsTableView = [[UITableView alloc] initWithFrame:ingredientsFrame style:UITableViewStyleGrouped];
    _ingredientsTableView.delegate = self;
    _ingredientsTableView.dataSource = self;
    _ingredientsTableView.tag = 1;
    [self.view addSubview:_ingredientsTableView];
    _modsTableView = [[UITableView alloc] initWithFrame:modsFrame style:UITableViewStyleGrouped];
    _modsTableView.delegate = self;
    _modsTableView.dataSource = self;
    _modsTableView.tag = 2;
    [self.view addSubview:_modsTableView];
}

See more ..

how to save an image in uitableviewcell to album with long tap

I use following code to get images from internet

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
   NSURL *imageUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",image_url, [dic objectForKey:@"imageurl"]]];
__block UIActivityIndicatorView *activityIndicator;
__weak UIImageView *weakImageView = cell.userinformationimageView;
cell.userinformationimageView.backgroundColor = [UIColor clearColor];

[cell.userinformationimageView sd_setImageWithURL:imageUrl placeholderImage:nil options:SDWebImageProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) {
    if (!activityIndicator) {
        [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]];
        activityIndicator.center = weakImageView.center;
        [activityIndicator startAnimating];
    }
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
    [activityIndicator removeFromSuperview];
    activityIndicator = nil;
}];
//more codes
}

there are so many cells and each cell has a image, and I add long tap

UILongPressGestureRecognizer * longPressGr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressToDo:)];
longPressGr.minimumPressDuration = 1.0;
[self.tableview addGestureRecognizer:longPressGr];

- (void)longPressToDo:(UILongPressGestureRecognizer *)gesture
{
if(gesture.state == UIGestureRecognizerStateBegan)
{
    CGPoint point = [gesture locationInView:self.tableview];
    NSIndexPath *indexPath = [self.tableview indexPathForRowAtPoint:point];
    if(indexPath == nil) return;
    NSLog(@"---->%d",[indexPath row]);
    NSDictionary *dic = [self.tableData objectAtIndex:indexPath.row];

}
}

so how can I get the image that i long tapped? I want to save it to album, thanks.

See more ..

UITableView insertion animation not displaying properly(?)

I'm struggling to get the insertion animation I want, at least what should happen isn't happening, I can't see what I'm doing wrong. Using the .Bottom and .Top UITableViewRowAnimations with insertRowsAtIndexPaths:withRowAnimation: don't produce the animations I expect. They both seem to affect the cell above or below the one I specify.

Can anyone please explain why (I may be mistaken)?

Here is all the relevant code:

@IBAction func add(sender: UIBarButtonItem) {
    model.pots.insert(Pot(name: "test", initial: 0, creationDate: NSDate(), startDate: NSDate(), expenditure: [], regularTopUps: [], extraTopUps: []), atIndex: 1)
    tableView.insertRowsAtIndexPaths([NSIndexPath(forItem: 1, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Bottom)
}

So for instance in this example, I would expect the new cell to slide in from beneath cell 0 and push cells 1-2 downward and take the cell 1 position. What actually happens is that the new cell takes the 1 position instantaneously and then the previous cells 1-2 slide down with the old cell 1 coming in from underneath the new cell. The funny thing is that if I instead use

@IBAction func add(sender: UIBarButtonItem) {
    model.pots.insert(Pot(name: "test", initial: 0, creationDate: NSDate(), startDate: NSDate(), expenditure: [], regularTopUps: [], extraTopUps: []), atIndex: 1)
    tableView.insertRowsAtIndexPaths([NSIndexPath(forItem: 0, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Bottom)
}

I get roughly the behaviour I expect. I have a similar problem with the .Top animation, but I don't think I have one with any of the others.

Help greatly appreciated.

See more ..

Not display all cells TableView

I have a tableview with custom cell and I have a problem when I want to add one, when I reload the tableview sometimes, the last cell not display totally. But when I restart the app, all tableviewcell display correctly. The problem appears most often on iPhone 4S and less often in iPhone 6. Do you have any idea what I suppose to do ?

See more ..

iOS: How to trigger a refresh of constraints/autolayout of a tableViewCell when its accessoryView changes?

I have got a custom tableview + custom cells that are constructed using constraint-based autolayout (all programmatically, no IB). In each cell there is (amongst others) a (potentially) multiline Label with text. The first calculation of autolayout is fine - i.e. the UILabel wraps correctly according to its textlength.

But I have a layout issue once I select a cell (i.e. change from UITableViewCellAccessoryNone to UITableViewCellAccessoryCheckmark) AND the number of needed lines for the UILabel.text should change - but instead remains the same.

I tried...

[myTableView reloadData];

and

[myTableView beginUpdate];
[myTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[myTableView endUpdates];

...in the delegate for cell-selection but had no success for updating the layout of the cell.

I suppose that I need to tell the system to reevaluate the constraints of the tableviewcell (specifically to reevaluate to preferredMaxLayoutWidth for the UILabel.) But I have no idea on how to do that the correct way. (I tried a few things with setNeedsUpdate but rather trial-and-error-style.)

Thanks in advance for pointing me in the right direction!

See more ..

All elements in custom UITableViewCell turn nil

I have a custom UITableViewCell called GenericRouteTableViewCell

@interface GenericRouteTableViewCell : UITableViewCell
@property (nonatomic, retain) IBOutlet UILabel *lblDirection;

I haven't done anything to the implementation file.

In my storyboard I have a regular UITableViewController, with 1 prototype cell.

  • Class of that prototype cell: GenericRouteTableViewCell
  • Reuse identifier of the prototype cell: GenericRouteTableViewCell
  • I've hooked up the labels to the outlets, haven't hooked up the cell anywhere in particular
  • I've set the cell height to 100

In the code of the UITableViewController

  • In viewDidLoad I call [self.tableView registerClass:[GenericRouteTableViewCell class] forCellReuseIdentifier:@"GenericRouteTableViewCell"];
  • In cellForRowAtIndexPath I do:

    static NSString *cellIdentifier = @"GenericRouteTableViewCell";
    GenericRouteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    [cell.lblDirection setText:@"test"];
    
    

The result:

I just get empty default cells, and when setting a breakpoint, the cell gets instantiated, I see my labels instantiated and before they are filled with values they are nilled.

What am I doing wrong?

Xcode 6.3, latest SDK

See more ..

NSIndexpath is shown as an DateTime?

I have an UITabelview with 2 sections

In my debug pane indexPath = (NSIndexPath)2001-01-01 00:00:00 UTC This looks to me like an DateTime format... Xcode bug? Any suggestions why this happens?

See more ..

move through the array of search from tableviewcontroller to viewcontroller

I made a list in tableviewcontroller, then add search bar and search display. All work fine but i need to add a button to return to the previous view. But I can not add searchbar and navigation bar - xcode does not permit to do so. I looked on the internet and it says that it is almost not real. Then i tried to change tableviewcontroller to viewcontroller. I do like: in .h file

@interface StreetTableViewController : UITableViewController

to

@interface StreetTableViewController : UIViewController

but in .m file i don't understand what I need to change. xcode give me an error in line NSIndexPath *indexPath = [[self tableView] indexPathForCell:cell]; on word tableView.what do I need to put in place of the word to make it work?

my code

        - (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        _items
        =  [NSArray arrayWithObjects:
             @"А",
             @"Ак",
             @"Ба",
             @"Бо",
             @"22", 
             @"23", 
             nil];
    }
    return self;
}

#pragma mark - UISearchDisplayDelegate

// register a cell reuse identifier for the search results table view
-(void)searchDisplayController:(UISearchDisplayController *)controller
 didLoadSearchResultsTableView:(UITableView *)tableView {
    [tableView registerClass:[UITableViewCell class]
      forCellReuseIdentifier:@"SearchResultsTableViewUITableViewCell"];
}

// perform the search
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString {
    NSPredicate *predicate
    = [NSPredicate predicateWithFormat:@"self beginswith %@", searchString];
    NSArray *searchResults
    = [[self items] filteredArrayUsingPredicate:predicate];
    [self setSearchResults:searchResults];

    return YES;
}

#pragma mark - UITableViewDataSource

// check if displaying search results
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
    if ([[self searchDisplayController] isActive]) {
        return [[self searchResults] count];
    } else {
        return [[self items] count];
    }
}

// check if displaying search results
-(UITableViewCell *)tableView:(UITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([[self searchDisplayController] isActive]) {
        UITableViewCell *cell
        = [tableView dequeueReusableCellWithIdentifier:@"SearchResultsTableViewUITableViewCell"
                                          forIndexPath:indexPath];
        id item = [[self searchResults] objectAtIndex:[indexPath row]];
        [[cell textLabel] setText:item];
        return cell;
    } else {
        UITableViewCell *cell
        = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                          forIndexPath:indexPath];
        id item = [[self items] objectAtIndex:[indexPath row]];
        [[cell textLabel] setText:item];
        return cell;
    }
}

#pragma mark - UITableViewDelegate

// manually perform detail segue after selecting a search result
-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([[self searchDisplayController] isActive]) {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        [self performSegueWithIdentifier:@"detailSegue" sender:cell];
    }
}

#pragma mark - UIViewController

/* prepare for detail scene segue
 called after cell selection in the master and
 search results table views */
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    UITableViewCell *cell = (UITableViewCell *)sender;

    id item = nil;
    if ([[self searchDisplayController] isActive]) {
        NSIndexPath *indexPath
        = [[[self searchDisplayController] searchResultsTableView] indexPathForCell:cell];
        item = [[self searchResults] objectAtIndex:[indexPath row]];
    } else {
        NSIndexPath *indexPath
        = [[self tableView] indexPathForCell:cell];
        item = [[self items] objectAtIndex:[indexPath row]];
    }

    UIViewController *detail
    = (UIViewController *)[segue destinationViewController];
    [[detail navigationItem] setTitle:item];
}
@end

See more ..

TableView rows inconsistent with data in Swift

I am loading a TableViewController with data from my Contact List. Everything works fine in the simulator with the small set of data, but on my iPhone with 82 contacts, I get a varying number of rows loaded, from 0, to most of the data, but never all of the data, and always a different amount. It's almost as though the table is being loaded and displayed before the data array is complete. If I set the numberOfRowsInSection return manually to 82 it works fine, but when set to contactdatalist.count it gets a lesser number. Is there something I am doing wrong, or can I slow down the tableview load until all the data load is complete? It seems asynchronous in operation.

import UIKit
import AddressBook

class TableViewControllerContacts: UITableViewController {
    
    var contactdatalist = [ContactData]()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
            
        self.contactdatalist = []

        let addressBook : ABAddressBookRef? = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
        ABAddressBookRequestAccessWithCompletion(addressBook, { (granted : Bool, error: CFError!) -> Void in
            if granted == true {
                let allContacts : NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
                for contactRef:ABRecordRef in allContacts { // first name
                    let myPBfirstname = ABRecordCopyValue(contactRef, kABPersonFirstNameProperty)?.takeRetainedValue() as! NSString? ?? ""
                    let myPBlastname = ABRecordCopyValue(contactRef, kABPersonLastNameProperty)?.takeRetainedValue() as! NSString? ?? ""
                    let phonesRef: ABMultiValueRef = ABRecordCopyValue(contactRef, kABPersonPhoneProperty)?.takeRetainedValue() as ABMultiValueRef? ?? ""
                    var phonesArray  = Array<Dictionary<String,String>>()
                    for var i:Int = 0; i < ABMultiValueGetCount(phonesRef); i++ {
                        let myPhLabel = ABMultiValueCopyLabelAtIndex(phonesRef, i)?.takeRetainedValue() as NSString? ?? ""
                        let myPhValue = ABMultiValueCopyValueAtIndex(phonesRef, i)?.takeRetainedValue() as! NSString? ?? ""
                        if myPhLabel.containsString("Mobile") {
                            self.contactdatalist.append(ContactData(firstname:myPBfirstname as String, lastname:myPBlastname as String, phone:myPhValue as String))
                        }
                    }
                }
            }
        })
        self.tableView.reloadData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return self.contactdatalist.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
        // Configure the cell...
        let contactdata = self.contactdatalist[indexPath.row]
        cell.textLabel!.text = ("\(contactdata.firstname) \(contactdata.lastname)")
        return cell
    }
See more ..

iOS UITableViewCell contents move on first scroll

You can see on the gif below that on the first scroll of UITableView cell's content moves a tiny bit. You can barely see it, margins become 1 pixel wider.I've never encountered this before. It seems like there's some layout issue before the first scroll and it resolves itself after the fact. There's no warning in XCode, these custom cells are pretty straightforward, with no layout code overrides.

I don't know where to start, how do I catch this glitch?

UPDATE. I've implemented an obvious workaround for now:

- (void)scrollTableToFixGlitch {

   [self.tableView setContentOffset:CGPointMake(0, 1)];
   [self.tableView setContentOffset:CGPointMake(0, -1)];

}
- (void)viewDidLoad {

   [super viewDidLoad];

   [self scrollTableToFixGlitch];
}

Still looking into the problem. I've tried generic UITableViewCells, nothing changed. Seems like it's the problem with View Controller's root view or tableview layout, and not with the table cells.

UPDATE 2.

I ruled out all the animations out of the question, problem lies somewhere in a different region. The glitch is easy to recreate on a much simplified project. My Tab Bar controller is based on MHCustomTabBarController with custom segues and some other additions. Here's what you do to recreate a glitch. Setup a project where your initial VC is embedded in Navigation Controller. The next controller either MHCustomTabBarController or a subclass is pushed to the navigation stack. First visible VC in tab bar is generic Table View Controller. That's it. Glitch appears only if tab bar controller is pushed in navigation stack.

Here's some code that I think matters from tab bar controller:

-(void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

   if (self.childViewControllers.count < 1) {
    [self performSegueWithIdentifier:@"viewController1" sender:[self.buttons objectAtIndex:0]];
  }
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if (![segue isKindOfClass:[MHTabBarSegue class]]) {
        [super prepareForSegue:segue sender:sender];
        return;
    }

    self.oldViewController = self.destinationViewController;

    //if view controller isn't already contained in the viewControllers-Dictionary
    if (![self.viewControllersByIdentifier objectForKey:segue.identifier]) {
        [self.viewControllersByIdentifier setObject:segue.destinationViewController forKey:segue.identifier];
    }

    [self.buttons setValue:@NO forKeyPath:@"selected"];
    [sender setSelected:YES];
    self.selectedIndex = [self.buttons indexOfObject:sender];

    self.destinationIdentifier = segue.identifier;
    self.destinationViewController = [self.viewControllersByIdentifier objectForKey:self.destinationIdentifier];

    [[NSNotificationCenter defaultCenter] postNotificationName:MHCustomTabBarControllerViewControllerChangedNotification object:nil]; 


}

And a custom segue code:

@implementation MHTabBarSegue
- (void) perform {


    MHCustomTabBarController *tabBarViewController = (MHCustomTabBarController *)self.sourceViewController;
    UIViewController *destinationViewController = (UIViewController *) tabBarViewController.destinationViewController;

    //remove old viewController
    if (tabBarViewController.oldViewController) {
        [tabBarViewController.oldViewController willMoveToParentViewController:nil];
        [tabBarViewController.oldViewController.view removeFromSuperview];
        [tabBarViewController.oldViewController removeFromParentViewController];
    }

    destinationViewController.view.frame = tabBarViewController.container.bounds;
    [tabBarViewController addChildViewController:destinationViewController];
    [tabBarViewController.container addSubview:destinationViewController.view];
    [destinationViewController didMoveToParentViewController:tabBarViewController];
}

@end

enter image description here

See more ..

How to resize UIScrollView/ContainerView's height according to UITableview number of rows?

This is my ViewController in the storyboard:

UIView (Controller)
-UIScrollView
--UIView
--UIView
--ContainerView
---UITableView (Embedded inside ContainerView)

The UITableView has dynamic prototypes.
My question is how do I change the UIScrollView and ContainerView's height to adapt to the UITableView's number of rows?

I want to be able to scroll down with my UIScrollView(not the UITableView's UIScrollView), when there are many rows inside the UITableView.

See more ..

Sort NSMutableArray as threaded comments

I'm developing an iOS app for website, that uses disqus comment system. So I'm trying to add feature for adding comments from this application.

My problem is that I don't know how to keep threaded structure, for example:

  1. Comment 1
    • Child 1.1
      • Child 1.1.1
      • Child 1.1.2
    • Child 1.2
      • Child 1.2.1
  2. Comment 2
    • Child 2.1

I found the solution in Java here java solution

It's almost works, but there is a big problem. It makes the structure be like this:

  1. Comment 1
    • Child 1.1
    • Child 1.2
      • Child 1.2.1
      • Child 1.1.1
      • Child 1.1.2
  2. Comment 2
    • Child 2.1

It ruins the relations between parents and children.
When I add a new child, it only knows how many children its parent has,in other words how many brothers this child has. But there is no information that the brother of this child also has children, in other words when I add a new child it doesn't know that it has nephews.

[threaded insertObject:child atIndex:i+[parent childCount]];

Please help me with this, I'm really stuck.

Here is the link, for test project link

And here is the code of sorting an array in objective-c

+ (NSMutableArray *)makeThreadedCommentsOutOf:(NSMutableArray *)comments{

    NSMutableArray *threaded = [[NSMutableArray alloc] initWithCapacity:0];

    //An array used to hold processed comments which should be removed at the end of the cycle
    NSMutableArray *removeComments = [[NSMutableArray alloc] initWithCapacity:0];

    //get the root comments first (comments with no parent)
    for(int i = 0; i < [comments count]; i++){
        Comment *comment = [comments objectAtIndex:i];
        if([[comment parentId] isEqual:[NSNull null]]){
            comment.commentDepth = 0;//A property of Comment to hold its depth
            comment.childCount = 0;
            [threaded addObject:comment];
            [removeComments addObject:comment];
        }
    }

    if([removeComments count] > 0){
        //clear processed comments
        [comments removeObjectsInArray:removeComments];
        [removeComments removeAllObjects];
    }

    int depth = 0;
    //get the child comments up to a max depth of 10
    while([comments count] > 0 && depth <= 10){
        depth++;
        for(int j = 0; j< [comments count]; j++){
            Comment *child = [comments objectAtIndex:j];
            //check root comments for match
            for(int i = 0; i < [threaded count]; i++){
                Comment *parent = [threaded objectAtIndex:i];
                if([[parent commentId] isEqualToString:[child parentId]]){
                    [parent setChildCount:[parent childCount]+1 ];
                    [child setCommentDepth:depth+[parent commentDepth]];
                    [threaded insertObject:child atIndex:i+[parent childCount]];
                    [removeComments addObject:child];
                    continue;
                    //break;
                }
            }
        }
        if([removeComments count] > 0){
            //clear processed comments
            [comments removeObjectsInArray:removeComments];
            [removeComments removeAllObjects];
        }
    }    
    return threaded;
}

See more ..

tableHeaderView with Autolayout not working correctly

Hey everybody i have a TableHeaderView like this:

enter image description here

Everything gets managed by Autolayout:

  • The UIImageView at the top should be always 2:1, so i set the Aspect ration and the Rest of the needed Constraints.

  • The 4 UIButtons should be always horizontal and should have the same Height and Width. So i worked with Equal Width and Equal Height and also with a Aspect Ratio of 1:1

  • And i have two UILabels with numberOfLines set to 0. I also made a Subclass of my UILabel, because of the preferredMaxLayoutWidth, like this:

    - (void) layoutSubviews
    {
    [super layoutSubviews];
    
    if ( self.numberOfLines == 0 )
    {
    if ( self.preferredMaxLayoutWidth != self.frame.size.width )
    {
        self.preferredMaxLayoutWidth = self.frame.size.width;
        [self setNeedsUpdateConstraints];
     }
     }
    }
    
    

This is my Code:

- (void)initializeHeaderViewLabels
{
 //After the Response from my server arrived i set the tableHeaderView with the Textdata
self.tableView.tableHeaderView = nil;

if((self.contentDict[@"title"]) != [NSNull null])
{
    self.headerTitleLabel.text = (self.contentDict[@"title"]);
}

if((self.contentDict[@"shortDescription"]) != [NSNull null])
{
    self.headerDescriptionLabel.text = (self.contentDict[@"shortDescription"]);
}

[self.headerView setNeedsLayout];
[self.headerView layoutIfNeeded];

CGFloat height = [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = height;
self.headerView.frame = headerFrame;

[self.tableView setTableHeaderView:self.headerView];

}

I get my Image and the Text for the UILabels from my Server, so i have to wait until the Response arrives, then i call initializeHeaderViewLabels.

My Problem is that the tableHeaderView is way too large during Runtime and so my UILabels get stretched and there is a lot of whiteSpace. Maybe i miss something?

EDIT1: Here is a screenshot during runtime, as you cann see there is a lot of space under the last UILabel:

enter image description here

EDIT2: Here are my Constraints for the 4 UIButtons:

enter image description here

EDIT3: Here are the Constraints for the UILabels:

enter image description here

See more ..

TableView didSelectRowAtIndexPath not called

So I have added a UITableView to a ViewController. I can't use a TableViewController 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?

  1. No, it's not didDeselectRowAtIndexPath.
  2. Yes all delegates and datasources are correct, since I can get the delegates/sources to trigger.
  3. Yes, Single Selection is set on the TableView in the inspector.
  4. 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.

See more ..

Set UITableViewCell contents only once? [duplicate]

I am using the MZTimerLabel library to display a countdown timer on each of my cells in a UITableView. I set the cell contents and countdown time of each cell in the function func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell. However, if I do this, I realized that if I scroll through my UITableView, the cells that the view cannot display have their countdown timer set again once I scroll back up to see the cells that weren't previously displayed. This is bad because the timer value is constantly changing between what was previously displayed before it went out of the view and what is currently displayed when it is back in the view. Is there a way to set the countdown timer for each UITableViewCell only once? I've looked at this link for help: UITableView :cellForRowAtIndexPath Continues being called but I'm not sure if there's any other way. Here is my code if that helps. Any help would be appreciated!

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return offerCellAtIndexPath(indexPath)
}


func offerCellAtIndexPath(indexPath: NSIndexPath) -> OfferCell{
    //Dequeue a "reusable" cell
    let cell = tableView.dequeueReusableCellWithIdentifier(offerCellIdentifier) as! OfferCell
    setCellContents(cell, indexPath: indexPath)
    return cell
}

func setCellContents(cell:OfferCell, indexPath: NSIndexPath!){
    let item = self.offers[indexPath.row]
    var expirDate: NSTimeInterval = item.dateExpired()!.doubleValue

    //Get current time and subtract it by the predicted expiration date of the cell. Subtract them to get the countdown timer.
    var currentDate = NSDate().timeIntervalSince1970
    var timer = MZTimerLabel(label: cell.timeLeft, andTimerType: MZTimerLabelTypeTimer)
    timer.delegate = self
    var countdownTime = expirDate - currentDate
    timer.setCountDownTime(countdownTime)
    timer.start()
}

See more ..

Odd enum memory issue in layoutSubviews

In the layoutSubviews of uitableviewcell, there is logics like

switch(enum_instance){ }

enum_instance was changed from some place, for instance in one timer, then setNeedLayout to trigger layoutSubviews

But the enum_instance in layoutSubviews will not be updated. Is this bug ? or something wrong I have done ?

Thanks,

See more ..

mercredi 29 avril 2015

Recognizing when the UITableViewCell delete button is shown

I have the following problem:

My UITableViewCell contains an UIButton and if the user swipes from right to left to show the deletion button the button in the Cell gets triggered sometimes.

Is there a way to recognize the swipe or that the deletion button is shown, so i could avoid that the buttons event gets triggered?

See more ..

Find out which TableView has been tapped

My ViewController has multiple TableViews and I added a UILongPressGestureRecognizer for the cells. Whenever the gesture has been called, I want to show up a popover. When I had just one TableView I could just use:

if let indexPath = tableView.indexPathForRowAtPoint(recognizer.locationInView(tableView)) {
    // code
}

Now I have multiple TableViews I don't know how to tell the method which TableView it should be using to find the indexPath.

Should I use custom GestureRecognizers just as identifiers? It doesn't seem a real good solution as I have to make a new GestureRecognizer for every TableView I have in this ViewController.

Can someone tell me an easy solution for this?

See more ..

Get values from a plist file in Xcode

I am creating a Plist file as shown below

enter image description here

I want to list all the Items where level is 1 and I can only use accessoryType = UITableViewCellAccessoryCheckmark if level is 1. How can I do it. My code for didSelectRowAtIndexPath is :

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *dic=[self.itemsInTable objectAtIndex:indexPath.row];
    if([dic valueForKey:@"SubItems"])
    {
        NSArray *arr=[dic valueForKey:@"SubItems"];

        BOOL isTableExpanded=NO;

        for(NSDictionary *subitems in arr )
        {
            NSInteger index=[self.itemsInTable indexOfObjectIdenticalTo:subitems];
            isTableExpanded=(index>0 && index!=NSIntegerMax);
            if(isTableExpanded) break;
        }

        if(isTableExpanded)
        {
            [self CollapseRows:arr];
        }
        else
        {
            NSUInteger count=indexPath.row+1;
            NSMutableArray *arrCells=[NSMutableArray array];
            for(NSDictionary *dInner in arr )
            {
                [arrCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
                [self.itemsInTable insertObject:dInner atIndex:count++];
            }
            [self.menuTableView insertRowsAtIndexPaths:arrCells withRowAnimation:UITableViewRowAnimationLeft];
        }
    }

    if([dic valueForKey:@"level"])
    {
//        NSArray *arr=[dic valueForKey:@"SubItems"];
//        if ([[arr objectAtIndex:0 ] intValue] == @"1")
        {
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

            if (cell.accessoryType == UITableViewCellAccessoryNone)
            {
                if(countId <5)
                {
                    cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    countId = countId + 1;
                }
                else
                {
                    UIAlertView *dialog;

                    dialog =[[UIAlertView alloc] initWithTitle:@"Alert Message"
                                                       message:@"Select maximum 5 countries"
                                                      delegate:self
                                             cancelButtonTitle:@"Cancel"
                                             otherButtonTitles:@"OK",nil];
                    [dialog show];

                    //            NSLog(@"Greater then 5");
                }
            }

            else
            {
                if(countId>0)
                {
                    cell.accessoryType = UITableViewCellAccessoryNone;
                    countId--;
                }
                else
                {
                    //show alert
                    UIAlertView *dialog;

                    dialog =[[UIAlertView alloc] initWithTitle:@"Alert Message"
                                                       message:@"Select atleast 1 country"
                                                      delegate:self
                                             cancelButtonTitle:@"Cancel"
                                             otherButtonTitles:@"OK",nil];
                    [dialog show];

                    //            NSLog(@"must choose 1");
                }

            }
            //    countId = [self.tableView indexPathsForSelectedRows].count;

            [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
        }
    }
}

Please do reply. I am stuck here

See more ..

How to display the picker when touch down the text field in static table view?

In TableViewController.h

- (IBAction)genderSelection:(id)sender;

In TableViewController.m

- (IBAction)genderSelection:(UIControl *)sender {
    
    
    ActionStringDoneBlock done = ^(ActionSheetStringPicker *picker, NSInteger selectedIndex, id selectedValue) {
        if ([sender respondsToSelector:@selector(setText:)]) {
            [sender performSelector:@selector(setText:) withObject:selectedValue];
        }
    };
    ActionStringCancelBlock cancel = ^(ActionSheetStringPicker *picker) {
        NSLog(@"Block Picker Canceled");
    };
    NSArray *gender= @[@"Male", @"Female"];
    [ActionSheetStringPicker showPickerWithTitle:@"Select a Block" rows:gender initialSelection:0 doneBlock:done cancelBlock:cancel origin:sender];
  
}

I'm using the [ActionSheetPicker-3.0]. I wish to display the picker ( the gender male or female). When the user touch down the text field , it's display the male or female picker . I try the code for normal view controller its work but not in the static tabletableviewController. Anyone know how to display the picker ?

The image: http://ift.tt/1JakX09

The picker is able to display in ViewController but not the static TableViewController.

The picker image: http://ift.tt/1OGeAso

See more ..

UITableviewCell automatic sizing based on label not working

UITableview cells are returning heights that don't really correlate to their text. I have been dealing with a rather annoying bug where xcode returns incorrect heights for cells and just in general is return pixels heights for elements in cells that are terribly inconsistent. I thought I could implement the methods below to clean things up, but they turned out just to make things worse. Here's a link to a google doc. The first image in the google doc is what my cells look like when I use these methods. Please tell me any ideas you have to fix them. The crux of the problem is a special case which I have shown in the second image of the google doc. The reason behind the special case and a deeper discussion of the reason it occurs is in the google doc. Here's the google doc link: http://ift.tt/1Ip6NKu

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section==0)  { //postcell
    return 500.0; //TODO add some autolayout stuff for this case...
} else  { //comment cell
    UIFont * font=[UIFont fontWithName:@"Helvetica Neue" size:13.0];
    NSIndexPath *adjustedIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section-1];
    BRComment *comment = [self.commentsController objectAtIndexPath:adjustedIndexPath];
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenWidth = screenRect.size.width;

    //CommentCell * commentCell=(CommentCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    CGSize labelHeight = [self heigtForCellwithString:comment.body andLabelWidth:screenWidth-78.0 withFont:font];
    return labelHeight.height; // the return height + your other view height
}
}

 -(CGSize)heigtForCellwithString:(NSString *)stringValue andLabelWidth:(CGFloat)labelWidth withFont:(UIFont *)font{
CGSize constraint = CGSizeMake(labelWidth,9999); // Replace 300 with your label width //TODO replace
NSDictionary *attributes = @{NSFontAttributeName: font};
CGRect rect = [stringValue boundingRectWithSize:constraint
                                        options:         (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                     attributes:attributes
                                        context:nil];
return rect.size;

}

See more ..

Glitch while using deleteRowsAtIndexPaths and reloadRowsAtIndexPaths together

I seem to have trouble using deleteRowsAtIndexPaths and reloadRowsAtIndexPaths together.

In didSelectRowAtIndexPath, reloadRowsAtIndexPaths is called to update the row.

In my custom ViewCell I'm using a delegate to delete a row in the TableView, using deleteRowsAtIndexPaths whenever I swipe this cell. The labels are set to move along with the swipe and returns if the conditions are not met.

Everything is working just fine until deleteRowsAtIndexPaths has been called to delete a row. From here on, the next cell behaves strangely and the labels are in a state as when the cell was about to be deleted.

To solve this problem I can use reloadData() instead, but I really want to know what causes this behavior instead of being forced to use reloadData() all the time.

Code for didSelectRowAtIndexPath:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    // Code to add item to datamodel
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}

Code for cellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = orderTableView.dequeueReusableCellWithIdentifier("orderViewCell") as! OrderViewCell
    let item = data[indexPath.row]

    cell.delegate = self
    cell.nameLabel.text = item.name;
    cell.amountLabel.text = item.amount
    cell.priceLabel.text = item.price

    cell.amount = item.amount;
    cell.name = item.name

    return cell
}

The method handling the deletion:

func deleteItem(name: String) {
    if let index = find(data.map { $0.name }, name) {
        data.removeAtIndex(index)
        let indexPath = NSIndexPath(forRow: index, inSection: 0)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Left)
    }
}

See more ..

UIDatePicker hour column invisble/unscrollable in custom table view cell

I am using a custom table view cell with a UIDatePicker in it. The auto layout dimensions on the UIDatePicker are fixed width and height (320x216) and pinned top-left corner. This all works as expected, I'm just including these details in case they affect this problem.

The problem is that the date picker's Hour column is invisible and I cannot scroll it. I can change it by tapping, but cannot see the changes in the picker itself, only read them off of the date property. If the picker is set to Date+Time, the Day column's text is clipped on the right.

enter image description here

I suspect this is a glitch caused by having a date picker within a table view (since I think picker's are backed by table views) but I'm not sure how to fix it.

(Using iPad iOS 8.3.)

See more ..

Mac OS X - Swift: How would I make a dynamic table / list?

I am extremely new to Mac development. How would I create a dynamic table / list like the one found in the default Mail app (how the messages are displayed)?

(I am looking for the Mac equivalent of iOS's UITableView / UITableViewController)

See more ..

UiTableViewDataSource best usage?

I'm having a bit of a hard time figuring out when to use the tableViewController as a tableViewDataSource and when to create my own subclass of TableViewDataSource for my project. Could anyone please explain this to me. Thanks!! :)

See more ..

Attributes NSDictionary construction crash

I am getting the following error when the app calls the line: NSDictionary *attributes = @{NSFontAttributeName: font}; Why?

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'

Here is the original code, which dynamically determines the height of a cell:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {




if (indexPath.row==0)  { //postcell
    return 500.0; //TODO add some autolayout stuff for this case...
} else  { //comment cell

    CommentCell * commentCell=(CommentCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    CGSize labelHeight = [self heigtForCellwithString:commentCell.bodyLabel.text andLabelWidth:commentCell.bodyLabel.frame.size.width withFont:commentCell.bodyLabel.font];
    return labelHeight.height; // the return height + your other view height
}

}

-(CGSize)heigtForCellwithString:(NSString *)stringValue andLabelWidth:(CGFloat)labelWidth withFont:(UIFont *)font{
CGSize constraint = CGSizeMake(labelWidth,9999); // Replace 300 with your label width //TODO replace
NSDictionary *attributes = @{NSFontAttributeName: font};
CGRect rect = [stringValue boundingRectWithSize:constraint
                                        options:         (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                     attributes:attributes
                                        context:nil];
return rect.size;

}

See more ..

UITableView is not reloading in Alamofire respond

Had problem with reloading the tableview in asyc call in Alamofire Restful lib. Anyone has clue what is going on in the code below.

    func searchProduct (searchString: String) -> Void{

    if count(searchString)>=3 {

        Alamofire.request(.GET, "http://restful_api_url", parameters: ["searchKey":searchString])
            .responseCollection { (_, _, products: [Product]?, error) in
                println(products)
                self.products = products!
                self.tableView.reloadData()//not loading the tableview
        }
    }

}

See more ..

Limiting text read by VoiceOver from a UILabel

I'm creating an app similar to Mail, where you have table view cells that have a message preview. The text usually doesn't all fit in the cell, so an ellipsis is displayed automatically. This works well for sighted users, however for VoiceOver users I've discovered it will continue to announce everything after the ellipses - the entire message is read. I don't want that behavior, I want it to stop at the ellipsis just like it does in Mail. How could this be solved?

cell.messagePreviewLabel.text = a_potentially_really_long_string_here

Is it a bad idea to set the text to the entire message? Do I need to perform some calculation to know how much of the text can be displayed then manually split it and add an ellipsis myself?

See more ..

When does it count from zero?

I have a UITableView with multiple prototype cells. I then have a NSMutableArray that stores the cellID's so I can retrieve them at cellForRow... Here is the code:

-(void)viewDidLoad {
    self.cellID = [[NSMutableArray alloc] initWithObjects:@"typeOfGraph", @"graph", @"time", nil];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *currentCellID = [self.cellID objectAtIndex:indexPath.row];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:currentCellID forIndexPath:indexPath];

    NSLog(@"%ld and %lu", (long)indexPath.row, (unsigned long)[self.cellID count]);
    ...
}

When I make an NSLog of indexPath.row and cellID.count, for the last indexPath I get:

indexPath.row = 2
cellID.count  = 3

Does it count from zero or not? When it calculates the indexPath.row, it seems like it does count from zero, but it doesn't seem like it does at cellID.count.

My question is, when and why doesn't it always count from zero?

See more ..

Strange behavior with reloadRowsAtIndexPaths

Current code:
Currently I have a TableView with a custom TableViewCell. Whenever a user swipes the TableViewCell, the row will be deleted through a delegate and the data gets updated.

The method handling the deletion:

func deleteItem(name: String) {
    if let index = find(data.map { $0.name }, name) {
        data.removeAtIndex(index)
        let indexPath = NSIndexPath(forRow: index, inSection: 0)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Left)
    }
}

didSelectRowAtIndexPath:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    // Add item to data
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}

cellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = orderTableView.dequeueReusableCellWithIdentifier("orderViewCell") as! OrderViewCell
    let item = data[indexPath.row]

    cell.delegate = self
    cell.nameLabel.text = item.name;
    cell.amountLabel.text = item.amount
    cell.priceLabel.text = item.price

    cell.amount = item.amount;
    cell.name = item.name

    return cell
}

Whenever a cell is being swiped, a constraint of auto-layout is getting modified resulting in 2 labels moving along the swipe gesture. A Bool keeps track whether the item should be deleted.
When it's false it doesn't get deleted and the constraint will be set to the original value.
When it's true the function deleteItem(_:) will be called through a delegate, see the code above.

The method for handling the swipe gesture:

func handlePan(recognizer: UIPanGestureRecognizer) {
    if recognizer.state == .Changed {
        // Handling the constraint etc.
    }

    if recognizer.state == .Ended {
        if delete {
            delegate!.deleteItem(name)
        } else {
            // Constraint set to original value
        }
    }
}

Problem:
It only happens when a row has been deleted. When a cell has been deleted, the next cell behaves strangely. Some kind of "jumping" occurs. I noticed reloadRowsAtIndexPaths uses two instances to display a cell, i.e. initially it uses instance1 to show a cell. After the reload has been called, instance2 will take the place of instance1 and vice versa.

When a deletion has taken place, the next cell has its instance2 in a state like when the cell has been swiped to delete, meaning the labels are not in place and jumping between instance1 and instance2.

To solve this problem I can use reloadData() instead, but I really want to know what causes this behavior instead of being forced to use reloadData() all the time.

See more ..

Vertical alignment issue after setting attributedText on a cell's detailTextLabel

I am using the default right detail UITableViewCell style so I can provide a label and a value on the right. I would like to utilize an NSAttributedString for the detail's text so that I can prepend a small $ symbol in front of the number. While this does work, it has caused the cell's textLabel to be pushed up higher and the detailTextLabel lower, so they’re not vertically centered in the cell anymore.

Do you know why setting a cell's detailTextLabel’s attributedText to a string that is simply two different font sizes would cause that to occur, and what can I do to resolve this?

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"$" attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:10]}];
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"1000" attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17]}]];
cell.detailTextLabel.attributedText = attributedString;

enter image description here

See more ..

Custom Sorting FetchedResultsController Swift

I'm using a fetchedResultsController to display my CoreData models in a UITableView. I have an attribute on the model named Group. I want that to show up alphabetically as section titles. That all works fine so far. However, I want one specific item (Favorites) to appear above all the other sections. I thought about using rank or something but I still want the group name to be the section title. Thanks for any help.

See more ..

Pass cell array item to another view controller

So this is a common question which I have been reading up on, I am still learning so please keep that in mind.

Basically my app currently lets you add an item to the tableview then when you select a cell from the table view it shows another view controller which is meant to display the detailed information for that cell.

Diagram

In my tableView implementation file .m, I have the code to go to the view controller when a cell is clicked:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    SelectedItemViewController *selectView = [[SelectedItemViewController alloc] initWithNibName:@"SelectedView" bundle:nil];

    [selectView.titleView setText:@"test"];

    [self performSegueWithIdentifier:@"showSelected" sender:indexPath];
}

The 'setText' piece of code was me just testing to see if I was able to change the textLabel in the ViewCellController.

When a user saves a new item, this is the following segue code that is called when it returns back to the TableView. 'toDoItem' is an NSMutableArray.

 -(IBAction)unwindToList:(UIStoryboardSegue *)segue {
    AddToDoItemViewController* source = [segue sourceViewController];
    ToDoItem* item = source.toDoItem;
    if (item != nil){
        [self.toDoItems addObject:item];
        [self.tableView reloadData];
    }
}

Obviously I am doing something wrong.

What I am trying to understand is how I can:

  1. Select a cell, take the data from that index in the array so not just the cell data, data includes: Title, Description, DueDate and completion.

  2. Display it in another view controller.

  3. Manipulate the completion boolean value and save it so it remains that way when clicked again.

I don't want a full answer just something to point me in the right direction so I can work it out on my own, Thanks!

See more ..

How can I make a custom UITableView refresh control?

I know how to add a refresh control to a UITableView but how can I make a custom one using my own image and animation?

See more ..

Get keyboard size on iOS 8 not working with external keyboard

Been looking at several SO post now, but none seem to help me. Just want a UITableViews bottom constraint to be set so that the keyboard never is on top of the tableview. Seems impossible in iOS 8. It work when using normal soft keyboard, but when removing it in simulator or using real hardware keyboard, it still thinks there is a soft keyboard.

The code:

var currentKeyboardHeight:CGFloat = 0.0

override public func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        var keyboardRect = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue()

        let windowRect = view.window!.convertRect(keyboardRect, fromWindow:nil)
        let viewRect = view.convertRect(windowRect, fromView:nil)

        let deltaHeight = viewRect.size.height - currentKeyboardHeight

        currentKeyboardHeight = viewRect.size.height
        tableViewBottomConstraint.constant = currentKeyboardHeight
        UIView.animateWithDuration(0.25, animations: { () -> Void in
            self.view.layoutIfNeeded()
        })

        println("show keyboard: \(currentKeyboardHeight)")
    }
}

func keyboardWillHide(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        var keyboardRect = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue()
        keyboardRect = self.view.convertRect(keyboardRect, fromView: nil)

        let deltaHeight = keyboardRect.size.height - currentKeyboardHeight
        currentKeyboardHeight = 0
        tableViewBottomConstraint.constant = currentKeyboardHeight

        UIView.animateWithDuration(0.25, animations: { () -> Void in
            self.view.layoutIfNeeded()
        })

        println("hideKeyboard \(currentKeyboardHeight)")

    }
}

When selecting a uitextview in the last tableviewrow only this is printed:

show keyboard: 260.0

which is Wrong. If then you turn on soft keyboard (cmd+shift+k):

show keyboard: 260.0
show keyboard: 297.0
show keyboard: 297.0

which is Correct. And then turn it off (cmd+shift+k):

hideKeyboard 0.0
show keyboard: 260.0
hideKeyboard 0.0

which is Correct

See more ..

keep UISwitch state of a prototype cell when changing ViewControllers

I have a UITableViewCell subclass where I have connected a UISwitch from a custom prototype cell. (data are passed in the Table View from a previous ViewController)

When I Change view controllers the state of the UISwitchchanges back to default I need some way to remember the state of the switch while navigating through the app. I have searched a few other topics, but nothing seemed to fall in my case.

Here is the code:

import UIKit

class TableViewCell: UITableViewCell {

@IBOutlet weak var myStaticSwitch: UISwitch!
@IBOutlet weak var cellLabel: UILabel!
@IBAction func mySwitch(sender: UISwitch) {

    if myStaticSwitch.on {
    self.cellLabel.text = "on"
    //Do other things
    }
    else {
        self.cellLabel.text = "off"
    //Do other things
    }
}



override func awakeFromNib() {
    super.awakeFromNib()

    // Initialization code
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

See more ..

Weird behavior when reloading cells containing textFields in dynamic tableView

I have a dynamic tableView with custom cells that each contain a textField and label. I want the following behavior:


A user taps the "Add" button, and the table inserts a cell at index 0, with the cell's textField becoming the first responder.

When the user finishes inputting data, the one-lined textField resigns as first responder and hides itself.

The cell's label then becomes visible, filled with the user input, and auto-resizes it's height to accommodate the input. The cell is resized at this time too.


I have code that does exactly this the first time a cell is added, but when more cells are added then it gets weird. The second added cell s textField does not become first responder and is filled with the text from the previous textField. Subsequent added cells appear blank, except every 6 blank cells, the first cell's text shows up.

What's going on, and how can I fix this?

Here's the demo showing this behavior:

enter image description here

Here's my code:

#define FONT_SIZE 16.0f
#define CELL_CONTENT_WIDTH 300.0f // This will change for different size!
#define CELL_CONTENT_MARGIN_WIDTH 10.0f
#define CELL_CONTENT_MARGIN_HEIGHT 20.0f

@interface ViewController ()

@property (strong) IBOutlet UITableView *tableView;
@property (strong) NSMutableArray *notesArray;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.notesArray = [NSMutableArray arrayWithObjects:@"Testo 1", @"This is a long string of text to show how the cell resizes to fit a variable height label.", @"Testo 3", @"Testo 4", @"Testo 5", nil];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    // Return the number of sections.
    return 1;
}

- (IBAction)addButtonTapped {

    NSMutableArray *indexPaths = [NSMutableArray array];
    [indexPaths addObject:[NSIndexPath indexPathForRow:0 inSection:0]]; // insert at first index

    [self.tableView setEditing:YES animated:NO]; // go into edit mode so cell has label hidden and textField visible

    // do the insertion
    [self.notesArray insertObject:@"" atIndex:0]; // placeholder for when user starts typing
    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView endUpdates];

    [self.tableView setEditing:NO animated:NO];
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField {

    NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0]; // first table cell
    HC_NoteCell *cell = (HC_NoteCell *)[self.tableView cellForRowAtIndexPath:path];

    cell.noteTextField.hidden = YES;
    cell.noteLabel.text = cell.noteTextField.text;
    cell.noteLabel.hidden = NO;

    [self.notesArray replaceObjectAtIndex:0 withObject:cell.noteTextField.text];

    [textField resignFirstResponder];

    // Need to reload rows so cell height can be recalculated
    [self.tableView beginUpdates];
    [self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];

    return YES;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.notesArray.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSString *text;
    text = [self.notesArray objectAtIndex:indexPath.row];

    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN_WIDTH * 2), 20000.0f);

    UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:FONT_SIZE];
    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:font
                                                                forKey:NSFontAttributeName];
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:attrsDictionary];

    CGRect paragraphRect = [attributedString boundingRectWithSize:constraint options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];

    CGFloat height = MAX(paragraphRect.size.height, 22.0f);

    return height + (CELL_CONTENT_MARGIN_HEIGHT * 2);

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"NoteCell";

    HC_NoteCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[HC_NoteCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    if (self.tableView.isEditing) {

        cell.noteLabel.hidden = YES;
        cell.noteTextField.hidden = NO;
        cell.noteTextField.delegate = self;

        [cell.noteTextField becomeFirstResponder];

    } else {

        cell.noteLabel.hidden = NO;
        cell.noteTextField.hidden = YES;
        cell.noteTextField.delegate = self;

        cell.noteLabel.text = [self.notesArray objectAtIndex:indexPath.row];
    }

    return cell;
}

@end

See more ..

How to ensure remotely-fetched images in UITableView cells always loaded?

I have gotten this question several times in job interviews: You have are UITableView and the user is scrolling very fast. How exactly do you make sure at all of the cells' images which are being loaded from a server are visible wherever the user scrolls to.

I can think of several techniques. For instance what I have done is use an operation queue, loaded with requests to fetch images, and when the user starts scrolling, empty the queue and fill it with requests for images wherever the user is going towards.

See more ..

Adding an NSManagedObject to an NSMutableArray via didSelectRowAtIndexPath

I have a Core Data project set up, I've got an NSFetchedResultsController working properly, the NSPredicates works properly, and now I'm onto doing something useful with the data displayed on the screen.

Right now, I have UITableViewCellAccessory working properly to toggle checked/unchecked cells, but I'm returning a nil when I try to add selectedManagedObject to myArrayOfManagedObjects via didSelectRowAtIndexPath.

What is the proper way add/remove an NSManagedObject to an NSMutableArray via didSelectRowAtIndexPath?

Here are the relevant properties:

@property (nonatomic, strong) NSManagedObject *selectedManagedObject;
@property (nonatomic, strong) NSMutableArray *myArrayOfManagedObjects;

Here's my viewDidLoad where the array I want to dump `NSManagedObject's is instantiated:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Standard Core Data Setup Stuff

    // Instantiate a list to store myArrayOfManagedObjects
    self.myArrayOfManagedObjects = [[NSMutableArray alloc]init];
}

Here's my didSelectRowAtIndexPath

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

        NSManagedObject *selectedManagedObject = self.selectedManagedObject;

        // Set the checkmark accessory for the selected row.
        // TODO: add the object to the array
        if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryNone) {
            [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
            // ** My problem lives here
            [self.myArrayOfManagedObjects insertObject:self.selectedManagedObject atIndex:indexPath.row];
            NSLog(@"Added %@ to myArrayOfManagedObjectsArray", selectedManagedObject.myObjectDescription);
            NSLog(@"myArrayOfManagedObjects contains %@", self.myArrayOfManagedObjects);
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
        } else {
            [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
            // ** My problem lives here
            [self.myArrayOfManagedObjects removeObjectAtIndex:indexPath.row];
            NSLog(@"Removed %@ from myArrayOfManagedObjectsArray", selectedManagedObject.myObjectDescription);
            NSLog(@"myArrayOfManagedObjects contains %@", self.myArrayOfManagedObjects);
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
        }
    }

See more ..

Create expandable UITableView with on-the-fly calculations using swift

I'm looking to implement TableView which has n predetermined sections and each section has m cells. Content of each section is calculated and results shown in real time (m is known after calculations are done - this can be worked around, if necessary). As m (and m * n) can be rather large, I want cells of each section to be hidden until section header is clicked (which should do nothing, when calculations for that section are not done yet). What makes this even more difficult, is that the text in each section header and cell can be of varying length and so I need to be able to dynamically change height of each cell.

I've been working on it for couple of days now and it seems really difficult to achieve. I'm not looking for code solution but rather some tips/hints or sources to look at from people that might have had the same kind of problem. Is this even feasible? I was wondering whether the effort is not worth it and instead of section headers I could use buttons that each take to respective TableView.

Thank you.

See more ..

Event handling in tableView

What I'm trying to do is handling touch events so that when i screen is getting touched, i want to take some action. For example changing background color The things i tried: // I subclassed table view controller

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        tableView.backgroundColor = UIColor.orangeColor()
    }

that didn't work, i suspected that tvc may not be first responder so that table view handles the touch events. So i tried:

 override func viewDidLoad() {
        super.viewDidLoad()
        tableView.resignFirstResponder()


    }

Also tried:

override func becomeFirstResponder() -> Bool {
        return true
    }

    override func canBecomeFirstResponder() -> Bool {
       return true
    }

None of them work. How can i handle events ? What I'm missing?

See more ..

UITableViewDataSource methods not calling

I know this question is asked by so many but i'm unable to display the array in tableview I have taken uitableviewcontroller which I'm getting array data from web service and i kept breakpoints and checked it's not going to numberOfSectionsInTableView and cellForRowAtIndexPath these methods .and no array data is displaying .how to solve this please help me.I have given datasource and delegate connections also

See more ..

UITableView Separator line disappears when cell is inserted at first position and bottom cell is selected

I have code as follows:

#import "TestTableViewController.h"

@interface TestTableViewController ()
@property (nonatomic,strong) NSMutableArray *testDataArray;
@end

@implementation TestTableViewController

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.testDataArray = [[NSMutableArray alloc] init];
  for(int i = 0; i < 20; i++){
    [self.testDataArray addObject:[NSString stringWithFormat:@"TestString - %@",@(i)]];
  }
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  return self.testDataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"testCell" forIndexPath:indexPath];
  cell.textLabel.text = [self.testDataArray objectAtIndex:indexPath.row];
  return cell;
}

- (IBAction)insertNewElement:(UIBarButtonItem *)sender
{
  [self.testDataArray insertObject:@"AAAAAA" atIndex:0];
  [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]]
                        withRowAnimation:UITableViewRowAnimationAutomatic];
}

As you see code is very simple. Storyboard is also standard:

enter image description here

But when I select third cell and insert new cell this happen (Newly inserted cell is without separator line):

enter image description here

I found one solution, but there is a problem with it.First it uses Private API, and second I'm not sure that this is good practice to do:

- (void)layoutSubviews {
  [super layoutSubviews];

  for (UIView *subview in self.contentView.superview.subviews) {
    if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
      subview.hidden = NO;
    }
  }
}

Is it possible, that this is bug in Apple?

See more ..

How to limit number of rows selected in uitableview

I am creating a tableView where I want to limit number of rows selected to 5. If 6th row is selected then a alert will appear stating that I can select only 5 rows. I can check and uncheck the rows but minimum 1 row and maximum 5 rows should be selected. How can I do it. My current code is as follows:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        countId = countId + 1;

    }

    else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
        countId--;
    }
//    countId = [self.tableView indexPathsForSelectedRows].count;

    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Where should I set the limit and how to use it? I am new to this so any help will be appreciated.

See more ..

Why do headers and footers follow movement of row when deleting it?

I'm building an app in Swift that relies heavily upon Table Views. It uses both headers and footers, as well as row deletion. For some strange reason when I perform a row deletion, the header and footer follows the sliding movement of the row to be deleted. The below screenshots explain what I mean.

enter image description here

How do you avoid this?

I'm implementing the delete function like this:

// Deleting
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {

        // Handling data source updating, cell row deletion, transition...

    }
}

See more ..

Click the status time to scroll up

//when i tap the statusbar for scroll up, it didn't response anything.

-(void)viewDidLoad {

    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateData) name:kRefreshNotification object: nil];

    [IDSSharedData getInstance].EditprofilesMode = NO;

    self.tableView.delegate = self;
    self.tableView.allowsSelectionDuringEditing = NO;
    self.tableView.allowsMultipleSelectionDuringEditing = YES;

    //hiding the extra lines on the table view
    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
    self.searchDisplayController.searchResultsTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
    UIRefreshControl *refresh = [[UIRefreshControl alloc]init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:kPullToRefresh];
    self.refreshControl = refresh;
    [refresh addTarget:self action:@selector(updateData) forControlEvents:UIControlEventValueChanged];

    //the problem is here i guess
    self.tableView.scrollsToTop =YES;
}

See more ..

Overlapping table view scrolls tableView behind it

Basically I have a compound view in my storyboard:

  • a UIView with with inputs. Let's call it View1
  • container view table displays tableView controller (View2)

Works fine.

I have a small issue when another displayed tableview from UIView overlaps the bottom View2 with its own results. Only cells that stays within the bound of the View1 can be interacted with and selected. The part of the tableView (autocomplete results) that actually overlaps View2 (and it looks like it is on top) scrolls the View2..

enter image description here

I already tried referencing View1 and setting View1.layer.zPosition to a higher value. It wouldn't help..

Any suggestions?

P.S: If this requires modifying the code Swift syntax is preferred over obj-c :)

See more ..

Searching through objects in array swift

I'm trying to create a search function using the UISearchController. However i cant seem to make it work with my Team Object. I've started by creating a Team Object which contain a id, name and shortname. Then i'm retrieving the teamData from a url and adding the Team Objects into an array which is populated into a tableView. This tableView contain a searchController which is suppose to filter the Data, but nothing happens.

arrays

var teamArray = Array<Team>()
var filteredTableData = [String]()

GetTeams function

func getTeams(url: String) {

    isApiCalling = true
    request(.GET, url, parameters: nil)
        .response { (request, response, data, error) in
            if error == nil {

                let data: AnyObject = data!
                let jsonArray = JSON(data: data as! NSData)
                for (key: String, subJson: JSON) in jsonArray {



                        // Create an object and parse your JSON one by one to append it to your array
                        var newTeamObject = Team(id: subJson["id"].intValue, name: subJson["name"].stringValue, shortname: subJson["shortname"].stringValue)


                        self.teamArray.append(newTeamObject)


                }


                self.isApiCalling = false
                self.tableView.reloadData()
                self.refreshControl?.endRefreshing()

            }
    }

}

CellForRowAtIndexPath

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("teamCell", forIndexPath: indexPath) as! TeamCell


    cell.textLabel?.font = UIFont(name: "HelveticaNeue-Light", size: 20)
    cell.textLabel?.text = self.teamArray[indexPath.row].name as String



    if (self.cellSelected.containsObject(indexPath)) {
        cell.accessoryView = cell.accessoryCheck
    } else {
        cell.accessoryView = cell.accessoryUncheck
    }


    return cell
}

FilterData

func updateSearchResultsForSearchController(searchController: UISearchController)
{
    filteredTableData.removeAll(keepCapacity: false)

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
    let array = (teamArray as NSArray).filteredArrayUsingPredicate(searchPredicate)
    filteredTableData = array as! [String]

    self.tableView.reloadData()
}

See more ..

How to know tableView.contentSize before viewDidAppear?

I say before (How get size between tableView and tabBar?) that going to programmatically draw cell.

For to know, how much cell to draw, I need tableView.contentSize.height, how to get it before viewDidAppear(), in viewWillAppear() I get not relevant size. If I draw in viewDidAppear() it is visibly for user, how Image is Appear.

See more ..

How can i resize image in table view?

How can I do something like in the picture in a table ? I was thinking that i can add a table view with a image and more custom cells.enter image description here My problem is:How can i resize image by dragging like this:enter image description here

See more ..

Deleting UITableViewCell: NSInternalInconsistencyException? [duplicate]

This question already has an answer here:

I'm getting an error when I try to delete a cell from my UITableView. I've looked at numerous links (this one for example is what I'm going off of. Below is my code:

var countdownTime = expirDate - currentDate
    timer.setCountDownTime(countdownTime)
    println("Count : \(self.offers.count)")
    timer.startWithEndingBlock { (countdownTime) -> Void in
        //If the times have expired, then delete the row
        self.tableView.beginUpdates()
        self.offers.removeAtIndex(indexPath.row)
        self.tableView.deleteRowsAtIndexPaths([indexPath.row], withRowAnimation: UITableViewRowAnimation.Fade)
        self.tableView.endUpdates()
    }
timer.start()

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return offers.count
}
//Only one section
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

I want to remove the cell when my timer has completed and the offers array is the array that I use to populate the UITableView. I was going off of this Assertion Failure -[UITableView _endCellAnimationsWithContext] which I thought would help me delete/insert rows correctly but I still get an error saying:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

Any help would be appreciated!

See more ..