115

I've created a UITableView in Interface Builder using storyboards. The UITableView is setup with static cells and a number of different sections.

The issue I'm having is that I'm trying to setup my app in several different languages. To do this I need to be able to change the UITableView section titles somehow.

Please can someone help me out? Ideally I'd like to approach the issue using IBOutlets however I suspect this isn't even possible in this case. Any advice and suggestions would be really appreciated.

starball
  • 20,030
  • 7
  • 43
  • 238
  • Note to future readers: ['Can somebody help me?' is not an actual question](https://meta.stackoverflow.com/a/284237/11107541). Make sure to ask clear, focused questions. – starball Dec 18 '22 at 22:42

8 Answers8

290

Once you have connected your UITableView delegate and datasource to your controller, you could do something like this:

ObjC

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    NSString *sectionName;
    switch (section) {
        case 0:
            sectionName = NSLocalizedString(@"mySectionName", @"mySectionName");
            break;
        case 1:
            sectionName = NSLocalizedString(@"myOtherSectionName", @"myOtherSectionName");
            break;
        // ...
        default:
            sectionName = @"";
            break;
    }    
    return sectionName;
}

Swift

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    let sectionName: String
    switch section {
        case 0:
            sectionName = NSLocalizedString("mySectionName", comment: "mySectionName")
        case 1:
            sectionName = NSLocalizedString("myOtherSectionName", comment: "myOtherSectionName")
        // ...
        default:
            sectionName = ""
    }
    return sectionName
}
Alladinian
  • 34,483
  • 6
  • 89
  • 91
  • You sure that actually gets called if you setup the story board using static cells? I doesn't seem like it's being invoked. – drewish Jul 03 '12 at 03:36
  • 7
    Ah it seems like you have to implement `numberOfSectionsInTableView:tableView:` to get it called. – drewish Jul 03 '12 at 03:54
  • For static cells, (most) all the other data source methods are not implemented. – wcochran May 20 '13 at 20:00
  • 2
    @drewish `numberOfSectionsInTableView:tableView:` implemented in IB for static cells. – wcochran May 20 '13 at 20:01
  • drewish is right - if you implement `numberOfSectionsInTableView:` , then the title method is called and overries the storyboard. Since this is a static tableview then it's pretty ok to override it with a method that returns a constant number @wcochran – GreatWiz Oct 19 '14 at 08:59
  • But how do you dynamically change the header? How do you invoke this method? – Blip May 23 '15 at 14:59
  • Just call the the reloadData() function from your UITableView instance. That way all data for your UITableView will be refreshed, this includes the invoke of the function from above. – BCI Dec 02 '15 at 10:52
17

If you are writing code in Swift it would look as an example like this

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
    switch section
    {
        case 0:
            return "Apple Devices"
        case 1:
            return "Samsung Devices"
        default:
            return "Other Devices"
    }
}
BCI
  • 465
  • 6
  • 19
10

Use the UITableViewDataSource method

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
geraldWilliam
  • 4,123
  • 1
  • 23
  • 35
6

titleForHeaderInSection is a delegate method of UITableView so to apply header text of section write as follows,

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    return @"Hello World";
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
iAnkit
  • 1,940
  • 19
  • 25
3

Note that -(NSString *)tableView: titleForHeaderInSection: is not called by UITableView if - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section is implemented in delegate of UITableView;

Julian D.
  • 321
  • 4
  • 11
2

I don't know about past versions of UITableView protocols, but as of iOS 9, func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? is part of the UITableViewDataSource protocol.

   class ViewController: UIViewController {

      @IBOutlet weak var tableView: UITableView!

      override func viewDidLoad() {
         super.viewDidLoad()
         tableView.dataSource = self
      }
   }

   extension ViewController: UITableViewDataSource {
      func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
         return "Section name"
      }
   }

You don't need to declare the delegate to fill your table with data.

Morgan Wilde
  • 16,795
  • 10
  • 53
  • 99
  • `extension` appears to not be needed with Swift 5.3. Xcode build messate: "'SettingsViewController' inherits conformance to protocol 'UITableViewDataSource' from superclass here" – marc-medley Jan 26 '21 at 06:32
2
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
   return 45.0f; 
//set height according to row or section , whatever you want to do!
}

section label text are set.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *sectionHeaderView;

        sectionHeaderView = [[UIView alloc] initWithFrame:
                             CGRectMake(0, 0, tableView.frame.size.width, 120.0)];


    sectionHeaderView.backgroundColor = kColor(61, 201, 247);

    UILabel *headerLabel = [[UILabel alloc] initWithFrame:
                            CGRectMake(sectionHeaderView.frame.origin.x,sectionHeaderView.frame.origin.y - 44, sectionHeaderView.frame.size.width, sectionHeaderView.frame.size.height)];

    headerLabel.backgroundColor = [UIColor clearColor];
    [headerLabel setTextColor:kColor(255, 255, 255)];
    headerLabel.textAlignment = NSTextAlignmentCenter;
    [headerLabel setFont:kFont(20)];
    [sectionHeaderView addSubview:headerLabel];

    switch (section) {
        case 0:
            headerLabel.text = @"Section 1";
            return sectionHeaderView;
            break;
        case 1:
            headerLabel.text = @"Section 2";
            return sectionHeaderView;
            break;
        case 2:
            headerLabel.text = @"Section 3";
            return sectionHeaderView;
            break;
        default:
            break;
    }

    return sectionHeaderView;
}
Manjeet
  • 101
  • 9
2

Nothing wrong with the other answers but this one offers a non-programmatic solution that may be useful in situations where one has a small static table. The benefit is that one can organize the localizations using the storyboard. One may continue to export localizations from Xcode via XLIFF files. Xcode 9 also has several new tools to make localizations easier.

(original)

I had a similar requirement. I had a static table with static cells in my Main.storyboard(Base). To localize section titles using .string files e.g. Main.strings(German) just select the section in storyboard and note the Object ID

Object ID

Afterwards go to your string file, in my case Main.strings(German) and insert the translation like:

"MLo-jM-tSN.headerTitle" = "Localized section title";

Additional Resources:

Tommie C.
  • 12,895
  • 5
  • 82
  • 100
igoMobile
  • 91
  • 6