UITableView reorder like Clear app - objective-c

How to start moving after the long tap detect? long tap detect with uilongpressgesturerecognizer.
My code:
`- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
flMoveRow = NO;
[self setEditing:YES animated:YES];
[listView reloadData];
}
- (void)longTapGesture:(UILongPressGestureRecognizer *)sender{
if((sender.state != UIGestureRecognizerStateEnded)&&(!flMoveRow)){
NSLog(#"==longTapGesture:");
flMoveRow = YES;
[listView beginUpdates];
NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
[listView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
[listView endUpdates];
sender.enabled = NO;
return;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"==canMoveRowAtIndexPath:%i -- %d", indexPath.row, (int)flMoveRow);
return flMoveRow;}`
break touch. Thanks.

There is a control available on cocoacontrols.com which mimics the Clear app. It is still being worked on apparently but when I downloaded it, it was still very impressive. You could either incorporate it fully in your app or use it as a starting point in your own research.
link.

Related

Xcode 9 - iOS 11 UITableView rows are empty

Ever since the new iOS 11 update, I have an app that will show blank tableview rows on the simulator and device. Even the row separators will not show for any of the rows that are supposed to be there. If I change the simulator to an older iOS version, the rows will show fine. No changes to code or storyboard.
The rows still have the data, meaning I can tap on one of the blank rows and it will execute the code and contain the information I was expecting.
It appears that other scenes that I have where the tableview is placed on a view and I don't use the built in text label work fine. Just this tableview class using the built in text label.
Here is my code for the tableview class...
#interface BunkPickTableViewController ()
#end
#implementation BunkPickTableViewController
#synthesize appDelegate, delegate, bunkPassedValue;
- (void)viewDidLoad {
[super viewDidLoad];
UIView *backgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
CAGradientLayer *bgLayer = [BackgroundLayer tanGradient];
bgLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:bgLayer atIndex:0];
self.tableView.backgroundView = backgroundView;
[self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
self.title = #"Bunk Codes";
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self navigationController] setNavigationBarHidden:NO animated:NO];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [appDelegate.bunkArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.backgroundColor = [UIColor clearColor];
}
Bunk *bunkObj = [appDelegate.bunkArray objectAtIndex:indexPath.row];
cell.textLabel.text = bunkObj.bunkId;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
Bunk *bunkObj = [appDelegate.bunkArray objectAtIndex:indexPath.row];
[delegate dismissBunkPop:bunkObj.bunkId];
[self.navigationController popViewControllerAnimated:YES];
}
#end
TableView Settings Image
I had this issue as well with IOS 11 showing blank cells.. but in IOS 10 was fine. My issue was that I was using a gradient which for whatever reason stopped the cell text from being shown. Removing the gradient resolved the blank cells.
This is probably because your tableView gets under bgLayer.
The problem seems to be in self.view.layer insertSublayer:bgLayer atIndex:0. I was using insertSubview at index 0 and I had the same problem. This is probably a bug in iOS 11 - if your tableView is defined in storyboard, it always gets pushed to back.
The best solution is to put the bgLayer inside the tableView.backgroundView.
NOTE:
You could also solve it by calling sendSubviewToBack on the bgLayer in viewDidAppear, but unfortunetaly, tableview cells are moving to back on every tableview reloaddata, so it is not a good solution.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.tableView.bounds;
gradient.colors = #[(id)[UIColor blackColor].CGColor, (id)[UIColor
grayColor].CGColor, (id)[UIColor
lightGrayColor].CGColor];
UIView *bgView = [[UIView alloc]
initWithFrame:self.tableView.bounds];
[self setBackgroundView:bgView];
[bgView.layer insertSublayer:gradient atIndex:0];
[self.tableView setBackgroundView:bgView];
Setting gradient layer for tableview's background view solved the problem for me. Upto iOS 10 we can directly insert sublayer to tableView but in iOS 11 layer should be inserted to UITableVIew's background view only.
In tandem with the aforementioned tableview subviews manipulation, this problem can also occur if your project existed pre Xcode 9 and you then checked Use Safe Area Layout Guides on your storyboard. Try unchecking that and see if it works.

iOS6 UITableView section header duplicates

I have an UITableView with expandable rows in section 4. When one row is expanded the others need to be collapsed. I reload specified rows and scroll table to have the expanded one on top. Here's the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == 4)
{
if (indexPath.row == 0)
{
if (hypoExpanded)
{
hypoExpanded = NO;
[self performSelector:#selector(reloadRowWithScrollForIndexPath:) withObject:indexPath afterDelay:kAnimationDelay];
}
else
{
hypoExpanded = YES;
moodExpanded = NO;
activityExpanded = NO;
NSArray *indexArray = [NSArray arrayWithObjects:indexPath, [NSIndexPath indexPathForRow:1 inSection:4], [NSIndexPath indexPathForRow:2 inSection:4], nil];
[self performSelector:#selector(reloadRowWithScrollForIndexArray:) withObject:indexArray afterDelay:kAnimationDelay];
}
... }
}
- (void)reloadRowWithScrollForIndexArray:(NSArray *)indexArray
{
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:((NSIndexPath *)[indexArray objectAtIndex:0]).row inSection:((NSIndexPath *)[indexArray objectAtIndex:0]).section] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (void)reloadRowWithScrollForIndexPath:(NSIndexPath *)indexPath
{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
switch (section)
{
case 1:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bgc-info"]];
break;
case 2:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"in-info"]];
break;
case 3:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bp-info"]];
break;
case 4:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"per-info"]];
break;
}
return nil;
}
Sometimes a random section header (1, 2 or 3) duplicates and overlays the cell that belongs to that section. Scrolling the table to make the section disappear doesn't help. When I scroll back the duplicated header still exists.
It only happens on iOS 6. Invoking performSelectorOnMainThread: is not helpful either. Also, without calling scrollToRowAtIndexPath: everything works fine. What could possibly cause this behaviour?
You can see a screenshot here:
I had the same problem. Check for uncommitted animation in your code
[UIView beginAnimations:nil context:NULL];
... should be committed below

MGSplitViewController as Modal not working correctly

I am trying to use an MGSplitViewController, but rather than having it set as the rootViewController, I want it to show modally. This is the code I am using so far
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath
{
if(splitViewController == nil)
{
self.splitViewController = [[MGSplitViewController alloc] init];
self.rootViewController = [[RootViewController alloc] init];
self.detailViewController = [[DetailViewController alloc] init];
}
[splitViewController setViewControllers:[NSArray arrayWithObjects:rootViewController, detailViewController, nil]];
if (NO) { // whether to allow dragging the divider to move the split.
splitViewController.splitWidth = 15.0; // make it wide enough to actually drag!
splitViewController.allowsDraggingDivider = YES;
}
splitViewController.delegate = detailViewController;
[rootViewController performSelector:#selector(selectFirstRow) withObject:nil afterDelay:0];
[detailViewController performSelector:#selector(configureView) withObject:nil afterDelay:0];
[self presentViewController:splitViewController animated:YES completion:nil];
}
This works almost fine, but the buttons in the detailViewController do not work. They do nothing. Also, when I click a button in the left panel, the text doesn't change in the detailViewController as it does in the same project.
Am I missing something?
I'm also working with MGSplitViewController, but it sounds to me like you need to set up some communication between your master and detail views. If you look at the demo project, you can see they use delegates to that effect.

not able to click the search bar tableview cell

I've got a tableview containing array of names. The search bar works perfectly filtering the names in the table view.
The problem is the didSelectRowAtIndexpath is not getting fired when clicking the search tableview cell. Could you help me out?
What is the thing that I'm missing? Should I include any special delegate to involve search tableview cell click.
Below is the image and code.
-(void)search
{
nameArray = [[NSMutableArray alloc] init];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 160, 44)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableViewFriendsList.tableHeaderView = searchBar;
}
- (void)searchDisplayController:(UISearchDisplayController *)controller
willShowSearchResultsTableView:(UITableView *)tableView
{
[tableView setRowHeight:70];
[tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.tableViewFriendsList) {
NSString *friendsID =[[[self.friendsDictionary objectForKey:#"data"] objectAtIndex:indexPath.row] objectForKey:#"id"];
[[FacebookHelper sharedFacebookHelper] postOnWallWithDelegate:self andID:friendsID];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"I ve come here");
NSString *friendsID =[friendsListIdArray objectAtIndex:indexPath.row];
[[FacebookHelper sharedFacebookHelper] postOnWallWithDelegate:self andID:friendsID];
}
}
You forgot to set
searchController.searchResultsDelegate = self;
I do something in one of my projects that may be of assistance:
// add gesture to detect when table view is being tapped so that keyboard may be dismissed
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(dismissKeyboard)];
gestureRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:gestureRecognizer];
Moreover I am wondering why you have a search bar within a table cell. Would you mind posting a screen shot of it in your app? I am afraid you may be doing more work than is necessary.

UITableviewController - Update specific Cells

I have created custom cells with a button that changes the state of a row from "availible" to "bought", and I also have an UIImageview which shows the state. I want the cell to redraw with the new state when the user presses the button.
I have been able to get the UIImage to be redrawn after the User scrolls the cell out of view. This is what I have so far:
Initialization
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = YES;
self.contentSizeForViewInPopover = CGSizeMake(600.0, 560.0);
//[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[self.tableView setRowHeight:60];
[self.tableView setBackgroundColor:[UIColor blackColor]];
}
Got only one section:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
And all items are in the "paketListe" array:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [paketListe count];
}
The cellForRow function only gets called, when the cell is out of view and when the cell is initially drawn.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"CellForRow called!");
PaketTableViewCell *cell = [[[PaketTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil] autorelease];
[cell setDelegate:self];
Paket *tempPaket = [paketListe objectAtIndex:[indexPath row]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *userDocumentsPath = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/%#/%#",userDocumentsPath, [tempPaket productID], [tempPaket previewPic]];
[cell setProductIndex:[indexPath row]];
//... Setting some Attributes in my custom cell, cut out for simplicity....
cell.backgroundColor = [UIColor clearColor];
return cell;
}
The code for the Button, this is a delegate call, so my custom sell calls [delegate buttonPushed:(int)];
- (void) buttonPushed:(int) myProductIndex {
NSLog(#"Pushed: %#", [[paketListe objectAtIndex:myProductIndex] productID]);
CoreDataWrapper *tempCDW = [[CoreDataWrapper alloc] init];
[tempCDW initCoreData];
Paket *tempPaket = [paketListe objectAtIndex:myProductIndex];
//Doing some work in Core Data an my "paketListe" array. Left out for simplicity...
[tempCDW release];
//Here it begins....
[[self tableView] reloadData];
[[self tableView] beginUpdates];
[[self tableView] reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:myProductIndex inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[[self tableView] endUpdates];
}
Now I tried the reloading with different commands... Reload the whole thing with just reloadData or the begin-/endUpdate thing. Nothing refreshes the cell. After several hours of reading I think I did everything right, but no refresh.
I appreciate any help.
Quick and dirty:
- (void)configureCell:(PaketTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
//Any cell-specific code
[cell setNeedsLayout]; //or [cell setNeedsDisplay];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Code to create any/a general cell
[self configureCell:cell];
return cell;
}
- (void) buttonPushed:(int) myProductIndex {
//Code to identify the cell in which your button is (use "super")
[self configureCell:cellForPushedButton];
}
I got to know your problem you have missed in reloadRowsAtIndexPaths "nil".
Do as i wrote below, it will work.
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:myProductIndex inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];