Giter VIP home page Giter VIP logo

aqgridview's Introduction

AQGridView

Winner of the Best Developer Tool/Helper award at iPadDevCamp 2010 in San Jose

Version 1.2 — 10 January 2011

By Jim Dovey
Originally written for the Kobo iPad Application

Used In These Applications:

Supporting AQGridView

People have asked how they can show their support. Other than implementing nice features & pushing them back upstream, you can always take a look at my Amazon Wish List.

Introduction

AQGridView is an attempt to create something similar to NSCollectionView on the iPhone. If CALayoutManager were available on the iPhone, specifically the CAConstraintLayoutManager, then this would be relatively easy to put together. However, since none of those exist, there’s a lot of work to be done.

AQGridView is based around the programming model of UITableView and its associated classes. To create this class I looked long and hard at how UITableView does what it does, and attempted to replicate it as closely as possible. This means that if you are familiar with table view programming on the iPhone or iPad, you will find AQGridView simple to pick up.

Similarities with UITableView

  • A subclass of UIScrollView.
  • Reusable grid cells, similar to UITableViewCell.
  • Data source and delegate very similar to those used with UITableView.
  • Immediate and batched changes to the content list (insert, remove, reorder, reload).
  • Similar change animations (top, bottom, left, right, fade).
  • Simple AQGridViewController provided which performs grid view setup for you, similar to UITableViewController.
  • Support for custom header and footer views.

Differences from UITableView

  • No sections— uses NSUInteger as its index location rather than NSIndexPath.
  • Data source can specify a desired minimum size for all grid cells.
  • Cells are not automatically resized to fit in layout grid— this can be changed via a property.
  • The delegate gets an opportunity to adjust the layout frame for each cell as it is displayed.
  • The grid layout is adjusted to fit the contentSize width. You can specify left and/or right padding to reach a size which can be divided into three, five, etc. cells per row.
  • A customizable ‘glow’ selection style, which places a glow around a cell’s layer (or a specified sublayer) using the shadowRadius property of CALayer. Note that this is only available in iPhone OS 3.2 or later.

Requirements

  • The iPhone OS 3.2 SDK is needed to build. It can however run on iPhones running OS 3.0 (iPhone/iPad universal app compatible).

How to get it

Download or clone it from GitHub

How to use it in your project

This project compiles to a static library which you can include, or you can just reference the source files directly. Note that there are some resources to copy into your project for the tableview-style selection backgrounds.

To include the project in your project named “MY_PROJECT”:

  1. Clone the repo
  2. Delete the .git file
  3. If desired delete the Examples folder
  4. Move the cloned AQGridView file folder to the desired location in your project file folder
  5. Add the cloned folder to your project repo with git add if desired
  6. From within Xcode, select “Add Files to ‘MY_PROJECT’”, select “AQGridView.xcodeproj” (leave the “Add to Targets” box checked)
  7. AQGridView should now appear in the Xcode Project Navigator / folder thing
  8. Click on the “MY_PROJECT” entry, Targets → MY_PROJECT → Build Phases → Target Dependencies → + “AQGridView”
  9. Click on the “MY_PROJECT” entry, Targets → MY_PROJECT → Build Phases → Link Binary with Libraries → + “libAQGridView.a”
  10. Click on the “MY_PROJECT” entry, Targets → MY_PROJECT → Build Settings → Search Paths → User Header Search Paths → + “AQGridView”
  11. Click on the “MY_PROJECT” entry, Targets → MY_PROJECT → Build Settings → Linking → Other Linker Flags → + “-ObjC”
  12. #import "AQGridViewController.h"
  13. AQGridViewController *grid = [AQGridViewController alloc];
  14. If this doesn’t work try tweaking some of the settings referenced in setup for https://github.com/Cocoanetics/DTCoreText

Overview

AQGridView has a number of supporting internal classes. The ones you’ll interact with directly are:

  • AQGridView
  • AQGridViewCell
  • AQGridViewController

Basic setup

Create a subclass of AQGridViewController. In -viewDidLoad you can change any properties you desire, add background, header, or footer views, and so on.

Unless you want a grid cell size of 96×128 (the default) you should implement the AQGridViewDataSource method -portraitGridCellSizeForGridView:, from which you can return a suitable minimum size for your cells. This is used as the basis of the layout grid; the grid view will expand the width of this size until it reaches a factor of the current content size, then uses that for its layout.

Cells will be placed in the center of each layout grid rectangle. By default, the cells are not resized to fill this grid rectangle, but you can change this using the resizesCellWidthToFit property of AQGridView. If your cell should not be positioned dead center (for example, if your cell contains an image with a shadow on one side, and the image should be centered, not the whole thing) then you can implement the AQGridViewDelegate method -gridView:adjustCellFrame:withinGridCellFrame: to tweak the auto-centered cell frame calculated by the grid view’s layout code. For instance, the Kobo iPad App does this for its shelf view, and uses resizesCellWidthToFit for its two-column list view.

Future Directions

  • Section support. This will need a large amount of refactoring to support moves between sections, and will need a new way of keeping track of visible cell indices (it currently uses an NSRange).
  • High-performance rendering. If cells don’t need to update their content after being drawn, each row could be composited into a single view for reduced load on the CoreAnimation renderer. This would need support in the grid view for displaying these composited rows, and would also need special support in KBGridViewCell to mark individual cells as needing dynamic updates, so they could be skipped when compositing and displayed normally on top of the composited row. KVO would be used to keep track of this. NB: This would also need special handling for the ‘glow’ selection style (or possibly the tracking cell would always be placed on screen, regardless of its dynamism requirements).
  • Content adjustments. There are possibly still a couple of deeply-buried bugs in the cell movement code inside KBGridViewUpdateInfo. These are a pain to track down, and the code in that class could possibly use some cleanup. This is also something which would need to change a lot for section support (it makes heavy use of NSIndexSet right now).

Known Bugs

  • Don’t try to pile multiple animations on top of one another. i.e. don’t call -beginUpdates on a grid view whose -isAnimatingUpdates method returns YES. Bad things will happen, cells will end up in the wrong places, stacked on top of one another.

Examples

All examples are located in the Examples folder.

ImageDemo

This is the demo which was presented at iPad Dev Camp in San Jose. It is primarily a showcase for automatic content reordering and animation, but also includes examples of the two main cell types: centered empty-space bordered cells, and filled line-separated cells.

Rotating the display will change the number of columns in the grid, with the associated animation. In addition, there are two buttons which cause items to be reordered. The top left button will shuffle the image order randomly, and the top right button will return everything to its original position.

The second button at the top right of the screen will pop up a menu which changes from the default empty-space grid style to a UITableView-like ‘filled cell’ grid style. In this version, the cells are automatically resized to fit their grid slots, and the selection style (and the cells’ behavior when selected) will match UITableView more closely.

SpringBoard

This is a new demo which shows how to use gesture recognizers to implement a manual reordering interface similar to that used by the iPad springboard. If you tap and hold on a cell for half a second, it will pop out of the grid, whereupon you can drag it around and drop it in a new position by letting go. The rest of the cells move out of the way as you drag your chosen cell around.

Additionally, it shows how to use the left and right insets to force the grid view to create the desired number of columns. In portrait mode, we want four columns, and the default width of 768 divides by four nicely, so we leave the insets at zero. In landscape mode we want five columns, and so we inset left & right by two pixels each to reduce the grid’s layout width to 1020 pixels, which is cleanly divisible by 5. As a result, rotating to landscape mode results in five columns being visible.

ExpanderDemo

This demo shows how to make a new grid view instance expand into existence from a single point. The ExpanderDemoViewController implements a basic grid view with a single cell. When this cell is tapped, it creates a new instance of ExpandingGridViewController, which then expands its image cells into view (only using those cells which would be visible, not ALL cells).

The expansion is triggered by calling the -expandCellsFromRect:ofView: method of ExpandingGridViewController. Before calling this, you must set the expanding grid view’s frame (so it can figure out what cells should be visible at what indices) and add it to a superview (so the passed rectangle can be mapped across). Afterward you should ensure that you call the new controller’s -viewDidAppear:. This last function implements the last part of the expansion algorithm.

In -expandCellsFromRect:ofView:, the controller converts the source rectangle into its own view’s coordinate space and caches it. It also goes through the grid view’s cell list and stores their existing frames ready to animate them later. Lastly, it sets its view’s background colour to clear. Then in -viewDidAppear: it first moves all the visible cells to the saved starting rectangle, then in an animation block it restores its background colour and moves the cells to their original positions.

Also: Yes, this example contains a memory leak, and doesn’t go in reverse. The only exemplary code is in the two methods discussed above.

aqgridview's People

Contributors

0xced avatar alanquatermain avatar aufflick avatar augard avatar choefele avatar chriswhite124 avatar cocoabits avatar darrylhthomas avatar dwineman avatar evadne avatar kevinlawler avatar marcusramberg avatar myell0w avatar ole avatar pjay avatar rbruels avatar rpetrich avatar steipete avatar stevenchan avatar techiemac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aqgridview's Issues

Crashes when deleting an item in second last row

App crashes when deleting items in second last row

This happens when

  • Content height is greater than grid view frame height
  • Scrolled to the bottom
  • Last row has only ONE item

It seems like the problem is in this line which adds NSNotFound to animatingDestinationIndices (AQGridView.m:1631, 5995654c1ed39a81a09e):
for ( AQGridViewAnimatorItem * item in _animatingCells )
{
[animatingDestinationIndices addIndex: item.index];
}

I got this from the debugger console:
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSMutableIndexSet addIndexesInRange:]: Range {2147483647, 1} exceeds maximum index value of NSNotFound - 1'
*** Call stack at first throw:
(
0 CoreFoundation 0x3587a987 exceptionPreprocess + 114
1 libobjc.A.dylib 0x34a8249d objc_exception_throw + 24
2 CoreFoundation 0x3587a7c9 +[NSException raise:format:arguments:] + 68
3 CoreFoundation 0x3587a803 +[NSException raise:format:] + 34
4 Foundation 0x3118d10d -[NSMutableIndexSet addIndexesInRange:] + 96
5 Foundation 0x3118d0a7 -[NSMutableIndexSet addIndex:] + 18
6 50k 0x0003589f -[AQGridView(AQCellLayout) updateVisibleGridCellsNow] + 3386
7 50k 0x000310bb -[AQGridView layoutSubviews] + 202
8 UIKit 0x341b80cf -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 26
9 CoreFoundation 0x35818bbf -[NSObject(NSObject) performSelector:withObject:] + 22
10 QuartzCore 0x31075685 -[CALayer layoutSublayers] + 120
11 QuartzCore 0x3107543d CALayerLayoutIfNeeded + 184
12 QuartzCore 0x3106f56d _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 212
13 QuartzCore 0x3106f383 _ZN2CA11Transaction6commitEv + 190
14 QuartzCore 0x31092f9d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 52
15 CoreFoundation 0x3580ac59 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
+ 16
16 CoreFoundation 0x3580aacd __CFRunLoopDoObservers + 412
17 CoreFoundation 0x358020cb __CFRunLoopRun + 854
18 CoreFoundation 0x35801c87 CFRunLoopRunSpecific + 230
19 CoreFoundation 0x35801b8f CFRunLoopRunInMode + 58
20 GraphicsServices 0x320c84ab GSEventRunModal + 114
21 GraphicsServices 0x320c8557 GSEventRun + 62
22 UIKit 0x341dc329 -[UIApplication _run] + 412
23 UIKit 0x341d9e93 UIApplicationMain + 670
24 50k 0x00002e2b main + 70
25 50k 0x00002de0 start + 40
)
terminate called after throwing an instance of 'NSException'

App crashes when deleting last gridviewCell in row

After deleting the last cell in row, the app crashes with the following NSRangeException.

* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSCFArray objectsAtIndexes:]: the last index (19) must be less than the count (19).'
2010-11-10 10:01:12.900 SpringBoard[2038:207] Stack: (
43575376,
44733228,
43312907,
43312746,
810502,
46066,
28950,
41543958,
41543205,
41486802,
41486130,
41686758,
43063890,
42853189,
42850472,
52562077,
52562274,
3117938,
9456,
9310
)
terminate called after throwing an instance of 'NSException'

Build fails with BUILTIN_IMAGES defined (the default)

Building from master (SHA: 2d86535)
OS X 10.6.6, Xcode 4 Release

CompileC /Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/Objects-normal/armv6/AQGridViewCell.o Classes/AQGridViewCell.m normal armv6 objective-c com.apple.compilers.llvm.clang.1_0.compiler
cd /Users/david/src/mascot/AQGridView
setenv LANG en_US.US-ASCII
setenv PATH "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/Users/david/bin:/Users/david/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/X11/bin:/Applications/MAMP/Library/bin:/Applications/SlickEditV1600Beta2.app/Contents/MacOS:/usr/local/CrossPack-AVR/bin:/usr/local/libexec/git-core:/Users/david/jruby-1.4.0/bin"
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -x objective-c -arch armv6 -fmessage-length=0 -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -std=c99 -Wno-trigraphs -fpascal-strings -O0 -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -gdwarf-2 -mthumb -miphoneos-version-min=3.0 -iquote /Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/AQGridView-generated-files.hmap -I/Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/AQGridView-own-target-headers.hmap -I/Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/AQGridView-all-target-headers.hmap -iquote /Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/AQGridView-project-headers.hmap -I/Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Products/Debug-iphoneos/include -I/Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/DerivedSources/armv6 -I/Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/DerivedSources -F/Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Products/Debug-iphoneos -include /Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/PrecompiledHeaders/AQGridView_Prefix-fetolvgujrgdbvacqubhqacgvuhc/AQGridView_Prefix.pch -DBUILTIN_IMAGES -c /Users/david/src/mascot/AQGridView/Classes/AQGridViewCell.m -o /Users/david/Library/Developer/Xcode/DerivedData/AQGridView-drwuiywfznqzqsbhctcmsrtjwrgx/Build/Intermediates/AQGridView.build/Debug-iphoneos/AQGridView.build/Objects-normal/armv6/AQGridViewCell.o

/Users/david/src/mascot/AQGridView/Classes/AQGridViewCell.m:314:5: error: use of undeclared identifier 'imageName' [2]
                                 imageName = @"AQGridSelectionGray.png";
                                 ^
/Users/david/src/mascot/AQGridView/Classes/AQGridViewCell.m:318:5: error: use of undeclared identifier 'imageName' [2]
                                 imageName = @"AQGridSelectionGrayBlue.png";
                                 ^
/Users/david/src/mascot/AQGridView/Classes/AQGridViewCell.m:322:5: error: use of undeclared identifier 'imageName' [2]
                                 imageName = @"AQGridSelectionGreen.png";
                                 ^
/Users/david/src/mascot/AQGridView/Classes/AQGridViewCell.m:326:5: error: use of undeclared identifier 'imageName' [2]
                                 imageName = @"AQGridSelectionRed.png";
                                 ^
4 errors generated.

gridView:cellForItemAtIndex: never called

Hi Alan,

Thanks for the great code!

I've been trying to implement AQGridView against an NSFetchedResultsController for about an hour now without much luck. It seems that numberOfItemsInGridView: is called as expected (and returns an integer greater than 0), but gridView:cellForItemAtIndex: is never called.

I set the delegate and datasource to the current instance, but it never seems to do anything. I'm happy to provide any information, but I'll have to obfuscate some of the details in my code if that's required.

On cell reordering

Do you think it’s a good idea to move code from the Springboard example back to the grid view itself?

Loading cells further off screen...

This is a feature suggestion: The ability to specify how many rows off the current view you would like pre-loaded. For instance, I extended AQGridView so you could specify that 2 rows of cells should be loaded above and below the visibleBounds, this helps ensure that the cells have all their content loaded by the time they become visible (in case you're loading content via threads or http).

Create grouping feature similar to UITableView

It would be nice to have the ability, much like the current iOS UITableView to support grouping.

I realize this is a potentially double edge sword (i.e. it would be bad for it to degenerate into a giant tree grid which tend to have usability issues) :)

Depending on how deep I can get into the code, I hope to also take a stab at this myself and give back a bit to the project.

AQGridViewCell contentView property is not labeled as IBOutlet

the AQGridViewCell contentView is not labeled as IBOutlet. This makes it very difficult to have a custom cell defined in a nib file without juggling views in awakeFromNib.

It seems to me AQGridView was not designed to accept custom cells defined in a nib file, though not much is needed to make it work.

Perhaps adding a 4th sample that does just that could help, something similar to the AdvancedTableViewCells sample code from Apple.

iOS4

Did you test/try it on iOS4?

Initializing AQGridViewController for a UIPopupController.

AQGridViewController cannot be used in a Pop Up like a Normal Table View can.
This code does not work.

fileTypePicker = [[[FileTypeViewController alloc] initWithStyle:UITableViewStylePlain] autorelease];
fileTypePicker.delegate = self;
self.fileTypePopover = [[[UIPopoverController alloc] initWithContentViewController:fileTypePicker] autorelease]
[self.fileTypePopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

Specifically initWithStyle: which crashes the App. How is the issue solved?

cannot set usesPagedHorizontalScrolling

there is no setter method for usesPagedHorizontalScrolling. The header implies that you can change this property to get a horizontally paged view, is this just incomplete right now?

Horizontal direction seems not to work

In the ImageDemo example, if you put the following line in the viewDidLoad method of the ImageDemoViewController:

self.gridView.layoutDirection = AQGridViewLayoutDirectionHorizontal;

you get the following error (backtrace here: https://gist.github.com/b87ae0e00ed585cc5fd2):

2010-06-04 00:17:46.198 ImageDemo[25683:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: (range.location >= 0) && (range.location + range.length <= [_visibleCells count])'

Additionally, if you reduce the height of the GridView to lets say 200px, you get an EXC_ARITHMETIC error (backtrace here: https://gist.github.com/15ffe23f2d2af3ff3921)

enqueueReusableCells: doesn't

In reloadData there is this call:

[self enqueueReusableCells: _visibleCells];

Inside which call there is this test:

- (void) enqueueReusableCells: (NSArray *) reusableCells
{
for ( AQGridViewCell * cell in reusableCells )
{
    if ( [_visibleCells containsObject: cell] )
    {
        NSLog( @"Warning: tried to add duplicate gridview cell" );
        continue;
    }

Clearly, this will be triggered every time. So we get a spurious warning. More problematic, the continue statement means that the cells will not be enqueued.

Since I have not analyzed the whole flow, I am a bit nervous about removing the test altogether. Could you confirm that this test is simply inappropriate?

Regards,

Jean-Denis

Cannot create custom cell in Interface Builder

Hi,

When I create my custom cells and use the same methods used for creating custom cells with interface builder in tableviews, it doesn't work, the cells are blank. Is there a fix? Or am I using the wrong approach?

Weird positions in debug mode

Hi,

I made a grid view which takes the half of the screen. It works fine when the ipad is not connected to the mac, but when connected and in debug mode, when I click anywhere on the screen (outside the grid view), it looks like the grid view takes this position as a click on one of its own cells.

What may you say about that?

Thanks,
Alex

Custom cell with TTImageView

I created my own cell which only contains ImageView. By using the UIImageView everything works as expected, but by just changing the UIImageView to TTImageView everything actually works except I am unable to pick a cell. When I click on a cell it does not get chosen.

Anyone with any ideas ?

Potential Leak

The static analyzer detects a potential leak on the last line of this method:

  • (NSSet *) animateCellUpdatesUsingVisibleContentRect: (CGRect) contentRect

UIPopover reference crashes on iphone

Hi,

on iphone 3g (os 3.1) the app crashes because of the references to UIPopoverController.
Target sdk is 3.2. Deploy sdk is 3.0
How can I fix it?

-c.

Cells Going Blanks... sometimes

This is relatively reproducible - sometimes when moving cells around and doing sorts by dragging, one of the other cells will go invisible. Re-moving a cell usually clears it up. This seems to occur when the message Warning: tried to add duplicate gridview cell gets printed to the console - twice in a row.

Sometimes scrolling will re-draw the cells appropriately, but at other times it will simply change which index becomes invisible.

Grid fails to display because dimensions are always 0 by 0.

I've added an AQGridView to a XIB file's main view, as done in the ImageDemoViewController example. The XIB's owner is a view controller derived from AQGridViewController. It's set up as the delegate; it's just like the ImageDemoViewController in the example.

Bu the grid is always blank, because numberOfItemsPerRow in AQGridViewData always returns 0, because _boundsSize width and height are always 0. My controller is getting called as the delegate, because numberOfItemsInGridView gets called.

It's too bad; this looks like a cool class.

AQGridViewCell reuseIdentifier property should not be read-only

Since it's not possible to set the identifier of the cell in Interface Builder, it has to be initialized in awakeFromNib. However this is not possible since the reuseIdentifier property is declared read-only in the @interface. This prevents me from doing the following in my cell subclass:

- (void)awakeFromNib {
    [super awakeFromNib];
    self.reuseIdentifier = @"CellIdentifier";
}

Note that this property is privately redeclared read-write in the implementation file, which lets AQGridViewCell do it in its initialization routines:

    self.reuseIdentifier = reuseIdentifier;

Of course, I can still do (and indeed I must do):

    _reuseIdentifier = @"CellIdentifier";

But that kind of defeats the idea of a property.

Of course, if AQGridViewCell was a subclass of UITableViewCell, this would be moot as I could set the identifier in IB.

AQGridView memory leak

I'm having some really weird memory leaks in my code, which seems to be caused by the AQGridViewCell contentView method, basically it looks like the _contentView object is not getting released, here is the Instruments screen shot http://andyzaharia.com/instruments_screenshot.png

And here is the source code where it happens http://andyzaharia.com/leaks.zip

I just spent an entire day trying to figure out why this happens and no luck so far, anyone can help ? :)

Thanks a lot, and thank you for this wonderful grid view !

Editing Info

I've to say that it's not an issue,it's instead an "help" request I hope it's the right place for asking
The problem I'm facing is that I'm not able to edit my gridView, at the moment I'm trying to delete some cell with no results.
What I've done so far:

  1. I've added the following method
- (void) gridView:(AQGridView *) aGridView 
        commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
        forRowAtIndex:(NSUInteger) index {

    NSLog(@"editing");
    NSIndexSet *visibleCellsIndex = [self.gridView visibleCellIndices];

    [self.gridView deleteItemsAtIndices:visibleCellsIndex
                            withAnimation:AQGridViewItemAnimationFade];
        [texmeDataObject.prunedDirContents removeObjectAtIndex:index];

        [editButton setStyle:UIBarButtonItemStyleBordered];
    [editButton setTitle:@"edit"];
}

I've the following action linked to a button
(void) toggleEdit:(id)sender {

   [self.gridView setEditing:!self.gridView.editing animated:YES];
   [editButton setTitle:@"delete"];
   [editButton setStyle:UIBarButtonItemStyleDone];

} 

this code don't work the method commitEditingStyle isn't called. I've looked in the examples but none of them delete some content. That's all, I hope someone can help me.
Last but not least sorry for my English :)

Can't set separator color

tried both

gridView.separatorColor = [UIColor redColor]
[gridView setSeparatorColor: [UIColor redColor]]

No luck. Also tried the same in your ImageDemo, but no luck again.

Horizontal scrolling no longer works as expected

It used to be that the horizontal scrolling wouldn't allow vertical scrolling. In many cases, this is desirable behavior. For example, if you have a grid that only scrolls horizontally in one orientation but allows vertical and horizontal scrolling when you move to another orientation.

Since the commit listed below, though, the content size of the grid is always forced to be one more pixel high than the grid size, meaning the grid will always scroll vertically, even if you don't want it to. I'm not sure why this commit was made or what problem it was solving, but it seems like an unnecessary thing to force. If anything, it should be available as a configurable option. Though I think it should be dropped altogether:

1e4fe3d#Classes/AQGridView.m

Trying to call gridview reloadData, not processing

Please forgive me if this is an obvious or brain-dead question - I'm still learning the ropes. I'm populating an array with image data on a return from the locationManager. Once that array is populated I want to load the gridview with those images. I've created a method called "showResultGrid" that receives the array of images and then calls [self.gridView reloadData] from within my veiwController. I'm getting to the point where the reloadData call is made - but the debugger just steps on past the line without going into reloadData. (I've stepped through ImageDemo, and I CAN step into reloadData) - so I must be missing something somewhere, but for the life of me I can't figure out what. Does this sound at all familiar? Are there any gotchas that I can check? THANK YOU for any help that you can provide!!

Crash in AQGridView.m on cell reordering

I come across this several times while playing with SpringBoard example code. To reproduce:

  1. Edit SpringBoardViewController.m:69 to
    _gridView.scrollEnabled = YES;
  2. Launch the example in ipad simulator

3. Try scrolling the gridview. The app will crash with following trace:

0   CoreFoundation                      0x011405a9 __exceptionPreprocess + 185
1   libobjc.A.dylib                     0x01294313 objc_exception_throw + 44
2   CoreFoundation                      0x011420bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3   CoreFoundation                      0x010b1966 ___forwarding___ + 966
4   CoreFoundation                      0x010b1522 _CF_forwarding_prep_0 + 50
5   RemoteDesktopSearch                 0x00011aad -[AQGridView(AQCellLayout) updateVisibleGridCellsNow] + 957
6   RemoteDesktopSearch                 0x0000bea5 -[AQGridView layoutSubviews] + 357
7   QuartzCore                          0x000f7a5a -[CALayer layoutSublayers] + 181
8   QuartzCore                          0x000f9ddc CALayerLayoutIfNeeded + 220
9   QuartzCore                          0x0009f0b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
10  QuartzCore                          0x000a0294 _ZN2CA11Transaction6commitEv + 292
11  QuartzCore                          0x000a046d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
12  CoreFoundation                      0x0112189b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
13  CoreFoundation                      0x010b66e7 __CFRunLoopDoObservers + 295
14  CoreFoundation                      0x0107f1d7 __CFRunLoopRun + 1575
15  CoreFoundation                      0x0107e840 CFRunLoopRunSpecific + 208
16  CoreFoundation                      0x0107e761 CFRunLoopRunInMode + 97
17  GraphicsServices                    0x01c871c4 GSEventRunModal + 217
18  GraphicsServices                    0x01c87289 GSEventRun + 115
19  UIKit                               0x00467c93 UIApplicationMain + 1160
20  RemoteDesktopSearch                 0x00001c44 main + 102
21  RemoteDesktopSearch                 0x00001bd5 start + 53

  1. Crash on AQGridView.m:1583
    removedIndices = [[[currentVisibleIndices aq_indexesOutsideIndexSet: newVisibleIndices] mutableCopy] autorelease];

Thanks!
Sam

crash while dragging cells

I'm experimenting with the code provided and it is really useful; however, I found that the sample (springboard) code crashes, if you reduce the number of icons down to 19, then try to move to an empty spot.

Cannot prevent selection using will* delegate methods

I'm trying to prevent selection of a cell by returning NSNotFound in the willSelect and willDeselect delegate methods for my grid, but it's not having any effect.

Looking in the source code, it looks like it is ignoring the return value of these delegate calls when it should be assigning the return value to the 'index' variable.

App crashes when deleting last grid view cell

When calling the method "deleteItemsAtIndices:(NSIndexSet *)indices withAnimation:(AQGridViewItemAnimation)animation;" in AQGridView.h on the very last cell in the grid, the app crashes with the following errors:

Assertion failure in -[AQGridView fixCellsFromAnimation], AQGridView.m:788

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'visible cell count after animation (17) doesn't match visible indices (18)'

I verified that the code is attempting to delete the proper index, and that it returns the correct number of cells after a cell is deleted.

Note that calling this method on any cell other than the very last one works as intended. Please let me know if you need more information.

Thanks!

AwakeFromNib missing or incorrect

I am still working on loading an AQGridView from a Nib file. In that context, two issues regarding awakeFromNib:

1- AQGridView doesn't have an AwakeFromNib method. This means that an AQGridView loaded from a Nib file is not properly set up. I propose:

- (void) awakeFromNib
{
    [super awakeFromNib];
    [self _sharedGridViewInit];
}

2- AQGridViewController does have an awakeFromNib method, but it fails to call [super awakeFromNib] as recommended by Apple. Change it to:

- (void) awakeFromNib
{
    [super awakeFromNib];
    [self _sharedGridViewDefaultSetup];
}

AQGridView as Static Library

Added the project into the Frameworks folder, made it a Direct Dependency in the app, as well as added the path for AQGridView to the Header Search Paths and User Header Search Paths. Added '-ObjC' and '-all_load' to Other Linker Flags since it is a 4.0 project. What else am I missing?

reload data does not update cells

I am testing AQGridView, where I load different data based on the filter defined and it's not updating cells when I call reloadData and still displays same cells. Just looking at the code, there seems to be a problem with animation as updateVisibleGridCellsNow method finds _animationCount > 0 and returns without updating the view. Please help.

NSLog

I'm getting a lot of NSLog console output from this line:

NSLog(@"%i >= %i ?", index, [_visibleCells count]);

It's in AQGridView.m, line 1594.

Is there any purpose to this? It might be a good idea to remove it in order to improve scroll performance.

SpringBoard - cell drops to bottom then back into place

Using the SpringBoard example I get a strange behavior when changing _gridview.scrollable to YES and increasing the items to e.g. 40:

Dragging cells around works as expected until the view is scrolled down. Once scrolled down, drag any cell and drop it at the new place. What happens is that the cell first moves all the way down out of screen and snaps then back to the new location.

AQGridViewCell: make it a subclass of UITableViewCell instead?

Hi,

Making AQGridViewCell a subclass of UITableViewCell would make it possible to use the Interface Builder Table View Cell standard item. Did you perhaps consider that idea and reject it? Is there some pitfall to take into account?

Conceptually, it makes quite a bit of sense also, as the two classes share a lot of behavior.

Crash when tapping anywhere, after moving (SpringBoard example)

When you first move a couple of SpringBoard icons, and then tap anywhere in the AQGridView, chances are good the app will crash. (This happens in both the SpringBoard example as my own app which uses the basic SpringBoard code to allow the user to move cells)

Why? Because for some reason hitView inside touchesEnded:withEvent: in AQGridView.m doesn't 'contain' a UIView, but an object of another type, that doesn't respond to the superview selector called on it on line 1287. This obviously results in an unrecognized selector sent exception: a crash.

Why hitView contains a random object, and not the tapped UIView however, I'm not sure... It probably has something to do with _touchedContentView not pointing in the right direction, as this is the object that's retained and then assigned to hitView.

PS. Sometimes the app doesn't crash when tapping after moving, this is because you're lucky and hitView actually points to an object that responds to superview, but it's almost never the UIView that hitView should be (the tapped view).

Latest SpringBoard code crashes when anything is clicked

Here is the error from Console:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'visible cell count after animation doesn't match visible indices'

And here is the stack trace:

Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 CoreFoundation 0x02879de4 TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION + 4
1 libobjc.A.dylib 0x93e7d509 objc_exception_throw + 56
2 CoreFoundation 0x0283a01b +[NSException raise:format:arguments:] + 155
3 Foundation 0x000ccf64 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 SpringBoard 0x00007cf0 -[AQGridView fixCellsFromAnimation] + 1520 (AQGridView.m:751)
5 SpringBoard 0x00008765 -[AQGridView cellUpdateAnimationStopped:finished:context:] + 97 (AQGridView.m:847)
6 UIKit 0x002ee288 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 249
7 UIKit 0x002efc82 +[UIViewAnimationState popAnimationState] + 2548
8 SpringBoard 0x0000864f -[AQGridView endUpdateAnimations] + 1111 (AQGridView.m:830)
9 SpringBoard 0x00008902 -[AQGridView _updateItemsAtIndices:updateAction:withAnimation:] + 195 (AQGridView.m:878)
10 SpringBoard 0x000089c2 -[AQGridView reloadItemsAtIndices:withAnimation:] + 58 (AQGridView.m:893)
11 SpringBoard 0x00003f07 -[SpringBoardViewController moveActionGestureRecognizerStateChanged:] + 2889 (SpringBoardViewController.m:277)
12 UIKit 0x0052e59a -[UIGestureRecognizer _updateGestureWithEvent:] + 641
13 UIKit 0x0052b0fb -[UIGestureRecognizer _delayedUpdateGesture] + 41
14 UIKit 0x0052f5a1 _UIGestureRecognizerUpdateObserver + 558
15 CoreFoundation 0x027fd8a2 __CFRunLoopDoObservers + 626
16 CoreFoundation 0x027c9ae5 CFRunLoopRunSpecific + 2709
17 CoreFoundation 0x027c9048 CFRunLoopRunInMode + 88
18 GraphicsServices 0x0303189d GSEventRunModal + 217
19 GraphicsServices 0x03031962 GSEventRun + 115
20 UIKit 0x002d0de1 UIApplicationMain + 1134
21 SpringBoard 0x00002858 main + 102 (main.m:14)
22 SpringBoard 0x000027c6 start + 54

custom imageview

hi,

i'm using your developed AQGridView for myself project. I have an question.

  • How do I add a button below the pictures ?
  • How do I imports a another project ?

Best regards,
AT

bounce = YES does not work properly

UIScrollView usually has bounce ability by setting the property. I've tried this:

AQGridView * contentView = [[AQGridView new] autorelease];
contentView.backgroundColor = [UIColor whiteColor];
contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
contentView.autoresizesSubviews = YES;
contentView.delegate = self;
contentView.dataSource = self;
contentView.resizesCellWidthToFit = NO;

    contentView.bounces = YES;
contentView.alwaysBounceVertical = YES;
contentView.alwaysBounceHorizontal = YES;

but nothing happens with Bouncing, seems like it does not work...

Repeating background?

I am playing with AQGridView to try to replicate a IBooks-like look and feel, with shelves and the like. I can't manage to display the background shelves properly:

  • resizing dynamically as the number of cells vary
  • scrolling in sync with the cells
  • respecting orientation, header and footer
  • with fixed-size left and right "shelf walls"

I am about to develop a custom tiling UIView subclass to set as the background view. Would that be the correct approach?

TIA

Jean-Denis

Differences between initWithFrame and awakeFromNib

AQGridViewCell initialization routines initWithFrame and awakeFromNib essentially do the same thing, except that initWithFrame also does:

_cellFlags.setShadowPath = 0;
_selectionGlowShadowRadius = 12.0f;

Are these two lines missing in awakeFromNib?

AQGridView does not handle translucent nav bar correctly

If you put an AQGridView in an AQGridViewController with a black translucent navigation bar, the view should be laid out so that it extends underneath the nav bar, and have a negative contentOffset.y value to show a blank area which is shown under the nav bar when scrolled to the top. This situation is not being accounted for in the layout code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.