• Stars
    star
    2,379
  • Rank 19,159 (Top 0.4 %)
  • Language
    Objective-C
  • License
    BSD 3-Clause "New...
  • Created over 14 years ago
  • Updated over 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A grid view for iPhone/iPad, designed to look similar to NSCollectionView.

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.

More Repositories

1

aqtoolkit

A toolkit consisting of a bunch of generally useful routines and extensions I wrote when putting together other projects.
Objective-C
787
star
2

iPhoneContacts

A wrapper for the iPhone's C-based AddressBook framework.
Objective-C
228
star
3

AQUI

A collection of SwiftUI views and utilities.
Swift
167
star
4

go-tmbundle

A TextMate bundle for the Go programming language.
Ruby
127
star
5

mac-app-store-validation-sample

An example of a working app store validation, with code signing checks.
C
107
star
6

SimpleHTTPServer

A simple HTTP server, implemented as a Mac command-line application. The source code, aside from main.m, is designed to work on either Mac or iOS.
Objective-C
89
star
7

AQAppStateMachine

An application state machine, based on matching values within bitfields to trigger actions supplied using Blocks.
Objective-C
87
star
8

iPad-Filesystem

A simple split-view-based filesystem browser for the iPad. Find out what you can read or write!
Objective-C
57
star
9

AQSocket

Trying out some asynchronous socket-level APIs using dispatch IO on iOS 5.
Objective-C
46
star
10

appencryptor

A command-line tool to apply or remove Apple Binary Protection from an application.
C
46
star
11

AQSelfRotatingViewController

A UIViewController subclass which implements its own auto-rotation logic, so its view can be placed directly into a UIWindow above other views.
Objective-C
39
star
12

GlassButton

A simple glass-effect UIButton subclass. It supports tinting although not brilliantly (it doesn't modify brightnesses). For best results, leave it alone for a slightly-smoked glass effect.
Objective-C
34
star
13

SwiftUIShareSheetDemo

A demonstration of how to display a share sheet in a SwiftUI application.
Swift
28
star
14

unirast

An attempt to reverse-engineer the UNIRAST raster graphics format used by AirPrint.
21
star
15

DownloadDarwinSource

An Automator workflow to download and extract the complete open source code of any OS X system release.
17
star
16

AQStreamDownloader

A simple class to download a stream to disk or to a memory block
Objective-C
16
star
17

ParserExample

An example project showing how to use the AQXMLParser, HTTPMessage, and AQGzipInputStream classes from AQToolkit.
Objective-C
13
star
18

secret-sauce

Sample code and projects from the Secret Sauce research paper presented at 360|MacDev 2010.
C
11
star
19

iPad-Plist-Viewer

A simple XML property list viewer. Designed to open .plist files from other apps.
Objective-C
11
star
20

NestedPlistEditor

A version of the 'defaults' command-line tool which allows editing of nested properties.
Objective-C
9
star
21

go-trie

A Trie structure implementation for Go, using Unicode runes as keys. Includes a customization for TeX-style hyphenation tries.
Go
9
star
22

cocoa-game-of-life

Simple Game of Life Application written in Objective-C using Cocoa
Objective-C
8
star
23

libdispatch-channels

An implementation of something like Go's channels for Grand Central Dispatch
C
8
star
24

time-machine

An example of in-app TimeMachine support, with a manager class to wrap the C API specifics.
Objective-C
7
star
25

AQWeakRetain

A pure-Foundation version of Omni Group's OFWeakRetain, for weak-retention of objects under manual memory management.
C
7
star
26

go-apns

A Go library for sending push notifications through the Apple Push Notification Service.
Go
7
star
27

AQXML

A complete and holistic XML processing framework in Objective-C. Currently a work in progress.
C++
6
star
28

dynamicpatch

Old code: Patching of PPC, Intel, and Rosetta, similar to Unsanity's APE. Worked on 10.4.2, probably doesn't any more.
C
6
star
29

bdk

The one, the only, the BackRow Development Kit.
Objective-C
6
star
30

atvloader

The original AwkwardTV software installer for the AppleTV.
Objective-C
5
star
31

swift-nio-protobuf

Codecs to aid in handling protocol buffers in your swift-nio pipeline.
Swift
5
star
32

H2Swift

HTTP2 library in pure Swift. Mostly for fun & learning, though I hope to make it close to nghttp2 in performance & capabilities at some point.
Swift
5
star
33

go-hyphenator

A TeX-style hyphenation package for the Go programming language.
Go
4
star
34

SetAppAffinity

A simple command-line app for OS X 10.6 which sets individual files to open using a specific application.
Objective-C
4
star
35

AQURLConnectionInputStream

Provides a means to link a custom NSURLRequest with the stream-based NSXMLParser API in OS X 10.7.
Objective-C
4
star
36

old-go-tmbundle

A TextMate bundle for the Go programming language.
3
star
37

AQOptionParser

A nice idiomatic Objective-C option parser, wrapping getopt_long() and providing localized usage output similar to RubyDoc.
Objective-C
3
star
38

AQInnerClass

Inner classes for Objective-C. Entirely blocks-based, so no ivars on inner classes (just capture from enclosing scope, similar to custom SecTransformRefs).
Objective-C
2
star
39

UntarAction

An automator action for OS X 10.6 which will take a list of tarfile paths/URLs and extract each one to the same directory.
Objective-C
2
star
40

iPhone-Legacy-SDK-Fixer

Fixes the 2.x iPhone SDKs such that they work on 10.6 (i.e. gcc-darwin-10).
Objective-C
2
star
41

go-gcm

Galois/Counter Mode cryptographic function implementation for Go.
Go
2
star
42

Beginning-ObjC-Project

From chapter 9 of Beginning Objective-C: A simple Core Data-based Contacts application with iCloud support, sandboxing (Address Book access only), and networked sharing of data via an included XPC bundle.
Objective-C
2
star
43

filesync-talk

Sample code accompanying my presentation on the File Coordination Cocoa APIs for Toronto CocoaHeads.
Objective-C
1
star
44

swift-zookeeper-support

Provides SwiftPM support for the Zookeeper C libraries.
Swift
1
star