Data Grid: Custom header sort arrows


Is there a way to replace the default sort arrows that show up in the header cells with custom graphics? The default arrows have a very pixelated, low resolution look.Thanks

Sub classing SDataGridCell
Sub classing SDataGridCell

Hi rggomes,

Thanks for getting in touch!

We are aware that the current sorting arrow images need tweaking to look smoother on retina devices.

Currently, we are aware that you can’t replace the sorting arrow images on a grid.

I have added this forum post to our update scheme so a member of the Shinobi Squad will update this forum post when a fix for this issue has been released.

Kind Regards,
Andrew Polkinghorn


Can we at least turn them off?

Swift: ShinobiDataGrid Get Header Click/Selected

Hi, the sort arrows are really a major annoyance. Please do something about them!


Hi, everybody. I also had this problem…is really bad not being able to custom your grid style  :rage:…but i figured out this problem  :sunglasses:. In order to change SGridSortOrderArrow you have to:

1.) Create a custom SDataGridHeaderCell class, this is my .h file:

#import <ShinobiGrids/SDataGridHeaderCell.h>
 #import <ShinobiGrids/SDataGridColumnSortOrder.h>
 @interface MyHeader : SDataGridHeaderCell
@property(nonatomic,assign)SDataGridColumnSortOrder sortOrder;

and this is my .m file (I use IconDrawer to draw an icons):

#import "MyHeader.h"
 #import "IconDrawer.h"
@implementation MyHeader
- (id)initWithFrame:(CGRect)frame
    self = [super initWithFrame:frame];
    if (self) {
         // Initialization code
- (void)drawRect:(CGRect)rect
    myBITheme thema = [ThemeConfiguratorgetCurrentTheme];
    UIImageView *sortImage;
    for (UIView* view in self.subviews) {
         if([NSStringFromClass ([view class]) isEqualToString:@"SGridSortOrderArrow"])
            sortImage = (UIImageView *)view;
             //remove image
            sortImage.image = nil;
             //set arrow down icon
            sortImage.image = [IconDrawer imageNamed:@"sortDown_" withColor:[thema firstSetColorNeutral]];
             //set arrow up icon
            sortImage.image = [IconDrawer imageNamed:@"sortUp_" withColor:[thema firstSetColorNeutral]];


2.) Before you load you grid or you call [yourGridreload] you have to set foe each column headerCellType (I have a method that set grid datasource):

for (SDataGridColumn* col in  yourGrid.columns) {
        col.headerCellType = [MyHeader class];

[yourGrid reload];
 2.) Change didChangeSortOrderForColumn method:
- (void)shinobiDataGrid:(ShinobiDataGrid *)grid didChangeSortOrderForColumn:(SDataGridColumn *)column
     ....//do my sorting
     // inform the grid that it should re-load the data
    [yourGrid reload];
     for (SDataGridColumn* col in  yourGrid.columns) {
        if([col.headerCell class]==[MyHeader class])
             ((MyHeader*)col.headerCell).sortOrder = SDataGridColumnSortOrderNone;
    if([column.headerCell class]==[MyHeader class])
      ((MyHeader*)column.headerCell).sortOrder = column.sortOrder;
 In this way you set custom  HeadecCell Class and override drawRect changing ImageView image



I have implemented as explained here. But when scrolling horizontally, because of the reuse of header cell , the sort symbol is displayed in some other column header after scrolling horizontally. I have more than 15 columns in my grid. So this solution wouldnt work.


Here is my solution for this. But still it is with Shinobi’s private APIs.

#import "SDataGridCustomHeaderCell.h"

@interface SDataGridCell (CustomSortArrows)
- (void) showArrowForSortOrder:(SDataGridColumnSortOrder)sortOrder sortMode:(SDataGridColumnSortMode)sortMode;

@implementation SDataGridCustomHeaderCell

// Method called to set the sort order.
- (void) showArrowForSortOrder:(SDataGridColumnSortOrder)sortOrder sortMode:(SDataGridColumnSortMode)sortMode {
    self.sortOrder = sortOrder;
    [super showArrowForSortOrder:sortOrder sortMode:sortMode];

- (void)drawRect:(CGRect)rect

    UIImageView * _sortImage = nil;
    CGRect textFieldFrame = [self.textField frame];
    textFieldFrame.origin.x = textFieldFrame.origin.x + textFieldFrame.size.width + 2.0f;
    textFieldFrame.size.width = 12.0f;
    textFieldFrame.origin.y = 1.0f;
    for (UIView * subView in self.subviews) {
        if([NSStringFromClass ([subView class]) isEqualToString:@"SGridSortOrderArrow"])
            _sortImage = (UIImageView *)subView;
            _sortImage.contentMode = UIViewContentModeCenter;
    if (self.sortOrder==SDataGridColumnSortOrderAscending) {
        _sortImage.image = [UIImage imageNamed:@"ascending.png"];
    } else if (self.sortOrder==SDataGridColumnSortOrderDescending) {
        _sortImage.image = [UIImage imageNamed:@"descending.png"];
    } else if (self.sortOrder==SDataGridColumnSortOrderNone) {
        _sortImage.image = nil;
    // Calculated frame for sort symbol
    _sortImage.frame = textFieldFrame;
    // Adjusting the textField's width to cover the space meant for sort symbol
    if (self.sortOrder==SDataGridColumnSortOrderNone) {
        CGRect tf = self.textField.frame;
        tf.origin.x = tf.origin.x + 12.0f;
        self.textField.frame = tf;


- (void)shinobiDataGrid:(ShinobiDataGrid *)grid didChangeSortOrderForColumn:(SDataGridColumn *)column from:(SDataGridColumnSortOrder)oldSortOrder
     //TODO: Add sorting code
    [grid reload];



Final grid


Has a way to edit the icons or the positioning or disable them completely been added yet? They currently overlap my header label text.


Hi Stubiell,

This is still something we will be seeking to do in the future but unfortunately not in the short term. I will update this thread when it does get completed.

Though if you are just interested in hiding the sortable header icons whilst maintaining sortable headers it should be possible to dig into the view hierarchy and set hidden on the appropriate view.

Kind regards,