Difference between revisions of "SBIconListView"

From iPhone Development Wiki
Jump to: navigation, search
(noting IconSupport)
m (Reference: Format)
 
(5 intermediate revisions by 3 users not shown)
Line 2: Line 2:
 
'''SBIconListView''' is a [[UIView]] subclass that contains list of icons ([[SBIconView]] objects). Each page on the home screen is a different instance of SBIconListView.
 
'''SBIconListView''' is a [[UIView]] subclass that contains list of icons ([[SBIconView]] objects). Each page on the home screen is a different instance of SBIconListView.
  
It is available in iOS 4-6, replacing [[SBIconList]]; this article is based on iOS 6. If you're developing a tweak that modifies icon layouts, make sure to use [[IconSupport]].
+
It is available in iOS 4-7, replacing [[SBIconList]]; this article is based on iOS 6. If you're developing a tweak that modifies icon layouts, make sure to use [[IconSupport]].
  
 
== Notable subclasses ==
 
== Notable subclasses ==
Line 16: Line 16:
  
 
== Edit mode and icon moving ==
 
== Edit mode and icon moving ==
Icon moving in edit/wiggle mode is not, contrary to expectations, related at all to where icons are located onscreen. If you have a 4x4 home screen but you play with the originForIconAtX:Y: values returned for each of these icons, you will notice that moving icons around will be exactly the same as it was before you changed their origins. Two methods, ''columnAtPoint:'' and ''rowAtPoint:'' estimate which column and row you are in according to the point passed in. Anyone wanting to make icon moving more natural for a modified layout would have to hook these methods accordingly.
+
Icon moving in edit/wiggle mode is not, contrary to expectations, related at all to where icons are located onscreen. If you have a 4x4 home screen but you play with the values returned by originForIconAtX:Y: (iOS 6) or originForIconAtCoordinate: (iOS 7) for each of these icons, you will notice that moving icons (by altering their origin, for instance) around will be exactly the same as it was before you changed their origins. Two methods, ''columnAtPoint:'' and ''rowAtPoint:'' estimate which column and row you are in according to the point passed in. Anyone wanting to make icon moving more natural for a modified layout would have to hook these methods accordingly.
  
 
== Icon coordinates ==
 
== Icon coordinates ==
All the icons in this view are backed by an index -- a NSUInteger. The indexes start from 0 for the icon at the top-left, to ''+[SBIconListView maxIcons] - 1''.  You can find icons' locations in the view by using ''-[SBIconListView originForIcon:]'', ''-originForIconAtIndex'', or ''-originForIconAtX:Y:''. Note, the last method does not always return a point within the view's bounds, but rather simply calculates it using simple math.
+
All the icons in this view are backed by an index -- a NSUInteger. The indexes start from 0 for the icon at the top-left, to ''+[SBIconListView maxIcons] - 1''.  You can find icons' locations in the view by using ''-[SBIconListView originForIcon:]'', ''-originForIconAtIndex'', or ''-originForIconAtX:Y:''.  
 +
* In iOS 7, these methods no longer accept separate arguments for the X and Y coordinate of an icon. Instead, it has been replaced by SBIconCoordinate:
 +
<source lang=objc>
 +
typedef struct SBIconCoordinate {
 +
    NSInteger row;
 +
    NSInteger col;
 +
} SBIconCoordinate;
 +
</source>
  
 +
* Methods that return the origin for an icon are not constrained to the list view's bounds, and are calculated via simple math.
 +
* An important difference between iOS 6 and 7 to watch out for is that while SBIconCoordinate begins from {row: 1, col:1}, the list view in iOS 6 beginning its icons' coordinates from {Y: 0, X: 0}. "However, rowAtPoint:, columnAtPoint:, rowForIcon:, columnForIcon: are still 0-indexed on iOS 7, which may cause some confusion."
 
There is also ''-iconAtPoint:'', which gives the icon for a CGPoint that is inside the list view's bounds.  
 
There is also ''-iconAtPoint:'', which gives the icon for a CGPoint that is inside the list view's bounds.  
  
Line 26: Line 35:
 
Hooking into the methods mentioned above is the best way to modify the position of an icon on the home screen, rather than explicitly modifying its frame with a bunch of hacks to detect changes.   
 
Hooking into the methods mentioned above is the best way to modify the position of an icon on the home screen, rather than explicitly modifying its frame with a bunch of hacks to detect changes.   
  
== Note ==  
+
== Notes ==  
If you ever mess up the contained icon views' frames too much, the following is magick.
+
If you ever mess up the contained icon views' frames too much, the following is magic.
    [listView setIconsNeedLayout];
+
<source lang=objc>
    [listView layoutIconsIfNeeded:kAnimationDuration domino:NO];
+
[listView setIconsNeedLayout];
 +
[listView layoutIconsIfNeeded:kAnimationDuration domino:NO];
 +
</source>
  
 
To get the SBIconListView instance containing an icon:
 
To get the SBIconListView instance containing an icon:
    id listViewForIcon(SBIcon *icon)
+
<source lang=objc>
    {
+
// Works on iOS 6 and 7.
        SBIconController *controller = [objc_getClass("SBIconController") sharedInstance];
+
static SBIconListView *IDWListViewForIcon(SBIcon *icon)
        SBRootFolder *rootFolder = [controller valueForKeyPath:@"rootFolder"];
+
{
        NSIndexPath *indexPath = [rootFolder indexPathForIcon:icon];
+
    SBIconController *controller = [objc_getClass("SBIconController") sharedInstance];
        SBIconListView *listView = nil;
+
    SBRootFolder *rootFolder = [controller valueForKeyPath:@"rootFolder"];
        [controller getListView:&listView folder:NULL relativePath:NULL forIndexPath:indexPath createIfNecessary:YES];
+
    NSIndexPath *indexPath = [rootFolder indexPathForIcon:icon];
        return listView;
+
    SBIconListView *listView = nil;
    }
+
    [controller getListView:&listView folder:NULL relativePath:NULL forIndexPath:indexPath createIfNecessary:YES];
 +
    return listView;
 +
}
  
== Reference ==  
+
</source>
* Header: https://github.com/caughtinflux/iOS-6-SpringBoard-Headers/blob/master/SBIconListView.h
+
 
 +
== References ==
 +
 
 +
<references/>
 +
* Header: https://github.com/caughtinflux/iOS-6-SpringBoard-Headers/blob/master/SBIconListView.h (iOS 6)
 +
* Header: https://github.com/caughtinflux/include/blob/master/SpringBoard/SBIconListView.h (iOS 7)
 +
 
 +
{{occlass|library=SpringBoard.app|navbox=1}}

Latest revision as of 14:17, 11 August 2015


SBIconListView is a UIView subclass that contains list of icons (SBIconView objects). Each page on the home screen is a different instance of SBIconListView.

It is available in iOS 4-7, replacing SBIconList; this article is based on iOS 6. If you're developing a tweak that modifies icon layouts, make sure to use IconSupport.

Notable subclasses

Description

SBIconListView is backed by a SBIconModel for the icons, and a SBIconViewMap, which handles the recycling of icon views, accessory updates, and some basic folder handling (nodes).

SBIconListView handles the rotation of lists, animations for app launching, transforms, icon additions, layouts, etc.

All the views of this class on the home screen are managed by the SBIconController singleton. Since it is just a subclass of UIView, it fits into the "View" of the "Model-View-Controller" paradigm. Thus, any changes made to the visible icons by this class are not saved. For modifying or adding icons, look at SBIconModel.

Edit mode and icon moving

Icon moving in edit/wiggle mode is not, contrary to expectations, related at all to where icons are located onscreen. If you have a 4x4 home screen but you play with the values returned by originForIconAtX:Y: (iOS 6) or originForIconAtCoordinate: (iOS 7) for each of these icons, you will notice that moving icons (by altering their origin, for instance) around will be exactly the same as it was before you changed their origins. Two methods, columnAtPoint: and rowAtPoint: estimate which column and row you are in according to the point passed in. Anyone wanting to make icon moving more natural for a modified layout would have to hook these methods accordingly.

Icon coordinates

All the icons in this view are backed by an index -- a NSUInteger. The indexes start from 0 for the icon at the top-left, to +[SBIconListView maxIcons] - 1. You can find icons' locations in the view by using -[SBIconListView originForIcon:], -originForIconAtIndex, or -originForIconAtX:Y:.

  • In iOS 7, these methods no longer accept separate arguments for the X and Y coordinate of an icon. Instead, it has been replaced by SBIconCoordinate:
typedef struct SBIconCoordinate {
    NSInteger row;
    NSInteger col;
} SBIconCoordinate;
  • Methods that return the origin for an icon are not constrained to the list view's bounds, and are calculated via simple math.
  • An important difference between iOS 6 and 7 to watch out for is that while SBIconCoordinate begins from {row: 1, col:1}, the list view in iOS 6 beginning its icons' coordinates from {Y: 0, X: 0}. "However, rowAtPoint:, columnAtPoint:, rowForIcon:, columnForIcon: are still 0-indexed on iOS 7, which may cause some confusion."

There is also -iconAtPoint:, which gives the icon for a CGPoint that is inside the list view's bounds.

Modifying icon locations

Hooking into the methods mentioned above is the best way to modify the position of an icon on the home screen, rather than explicitly modifying its frame with a bunch of hacks to detect changes.

Notes

If you ever mess up the contained icon views' frames too much, the following is magic.

[listView setIconsNeedLayout];
[listView layoutIconsIfNeeded:kAnimationDuration domino:NO];

To get the SBIconListView instance containing an icon:

// Works on iOS 6 and 7.
static SBIconListView *IDWListViewForIcon(SBIcon *icon)
{
    SBIconController *controller = [objc_getClass("SBIconController") sharedInstance];
    SBRootFolder *rootFolder = [controller valueForKeyPath:@"rootFolder"];
    NSIndexPath *indexPath = [rootFolder indexPathForIcon:icon];
    SBIconListView *listView = nil;
    [controller getListView:&listView folder:NULL relativePath:NULL forIndexPath:indexPath createIfNecessary:YES];
    return listView;
}

References