iOS Question How to set TableView Section Header size, color etc

Derek Johnson

Active Member
Licensed User
I'm trying to set the Size, Color etc of the section headers in a Tableview.

It appears possible to do this using Objective-C but I can't figure out how.

[Short summary - to save you reading the whole thing, it turns out that you can't do this unless you are prepared to implement all the methods of a TableView in Objective C. :( ]

I thought it might be possible to replace a Section Header with a Label with this code

B4X:
Sub ChangeSectionHeader(Table As TableView)
    Dim MyView As Label
    MyView.Initialize("Section")
    MyView.Text="Custom Header"
    MyView.Color=Colors.Blue
    MyView.Height=60dip
    MyView.TextColor=Colors.Red
 
    Try
        Dim no As NativeObject = Table
        no.RunMethod("willDisplayHeaderView:", Array (True,MyView,0))
    Catch
        Log(LastException)
    End Try
 
End Sub
but I get this exception when I try it:

<B4IExceptionWrapper: Error Domain=caught_exception Code=0 " Method not found: willDisplayHeaderView:, target: <UITableView: 0x17101600; frame = (357.838 248.686; 328.266 238); clipsToBounds = YES; hidden = YES; gestureRecognizers = <NSArray: 0x16d93b50>; layer = <CALayer: 0x16d8deb0>; contentOffset: {0, 387}; contentSize: {328.26596, 624.84717}>" UserInfo={NSLocalizedDescription= Method not found: willDisplayHeaderView:, target: <UITableView: 0x17101600; frame = (357.838 248.686; 328.266 238); clipsToBounds = YES; hidden = YES; gestureRecognizers = <NSArray: 0x16d93b50>; layer = <CALayer: 0x16d8deb0>; contentOffset: {0, 387}; contentSize: {328.26596, 624.84717}>}>
I think that I'm sending the message to the wrong object, but not sure.

What am I doing wrong?
 
Last edited:

Derek Johnson

Active Member
Licensed User
JanPro,

Thanks - I missed off the bit of Objective-C that I was trying to call:

B4X:
#if objc
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    // Background color
    view.tintColor = [UIColor blackColor];

    // Text Color
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
    [header.textLabel setTextColor:[UIColor whiteColor]];

    // Another way to set the background color
    // Note: does not preserve gradient effect of original header
    // header.contentView.backgroundColor = [UIColor blackColor];
}

#end if
but this code is not being reached I think .
 

JanPRO

Well-Known Member
Licensed User

Derek Johnson

Active Member
Licensed User
Thanks for this suggestion, I've looked at this article, and just tried it. I managed to work round most of the issues involving the section numbering by creating a real section header with no header title and no footer title, followed by a table item that is formatted to look like a section header. I also put tags on the table items so that I could distinguish between pseudo-headers and standard table items.

This is my code for setting up a Custom Section Header if anyone is interested:

B4X:
p_TableView is a Globally defined tableview
objAnchor is a reference TextField used for positioning

Sub InsertHeader(SectionHeader As String)
  
    'This creates an invisible section divider and increments the section number
    p_TableView.AddSection("","")
  
    Dim tc As TableCell = p_TableView.AddSingleLine("")
    tc.Bitmap=Null
    tc.ShowSelection = False
  
    Dim p As Panel
    p.Initialize("")
    p.Width = objAnchor.Width
    p.Height = objAnchor.Height
    p.Tag="Header"

    Dim Myview As Label
    'Can set these as required
    Myview.Initialize("Header")
    Myview.Text=SectionHeader
    Myview.Color=Colors.white
    Myview.Height=objAnchor.Height
    Myview.TextColor=Colors.Red
  
    p.AddView(Myview,10dip,0,p.Width,p.Height)
    tc.CustomView = p
End Sub
One thing that I couldn't manage to achieve however was the effect whereby the current section header appears at the top of the scroll area as you scroll down to later sections.

[Edit added later: I've also discovered an issue when the device is rotated. The Panel and Label in the above example needs to be re-sized and moved. I've had to add code to remember the objects and then to update them in the Page_Resize event. Will update the example at some point]

I still couldn't figure out how to re-format the actual section headers using your Objective-C and my previous guesses.

B4X:
#If objc
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return anyView;
}
#End If
In the above code anyView is obviously undefined and I wasn't sure what to set it too.
 
Last edited:

JanPRO

Well-Known Member
Licensed User
I still couldn't figure out how to re-format the actual section headers using your Objective-C and my previous guesses.
Something like

B4X:
#If objc
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        UILabel*label =[[UILabel alloc] init];
    label.textColor =[UIColor blackColor];
    label.backgroundColor =[UIColor whiteColor];
    label.text = @"test";
   
    return label;
}
#End If
 

Derek Johnson

Active Member
Licensed User
To make it work you should change the tableview delegate to your module where you are using inline objc.
Sorry - I can't figure out how to do that. Could you explain what that would look like - I've having great trouble understanding and working with delegates of objects.
 

JanPRO

Well-Known Member
Licensed User
Changing the tableview delegate
B4X:
Dim NaObj As NativeObject = TableView1
NaObj.RunMethod("setDelegate:",Array(Me))
NaObj.RunMethod("setDataSource:",Array(Me))
means also, that the B4i methods for the TableView wouldn't work any more. So you have to do all operations for the tableview with inline objc code ...
 

Derek Johnson

Active Member
Licensed User
means also, that the B4i methods for the TableView wouldn't work any more. So you have to do all operations for the tableview with inline objc code ...
Aargh!! :(

I don't think I'll be going down that route - sounds decidedly scary, but thanks for your patient help.
 
Top