I'm doing some porting from Qt Cocos2d to iOS cocos2d, am using Objective-C++ as the language for minimal efforts, now I'm wrapping the NSMutableArray in a C++ class for easier porting, basically this is my class
QList.h
#ifndef QLIST_H
#define QLIST_H
#import <Foundation/Foundation.h>
class QList {
NSMutableArray* List;
public:
QList();
~QList();
void append(id);
id at (int i);
int size();
bool isEmpty();
id takeLast();
id last();
void prepend(id);
id takeAt(int i);
id takeFirst();
void clear();
};
#endif
QList.mm
#ifndef QLIST_MM
#define QLIST_MM
#import "QList.h"
QList::QList() {
List = [[NSMutableArray alloc] init];
}
QList::~QList() {
[List autorelease];
List = nil;
}
void QList::append(id object) {
[List addObject:object];
}
id QList::at(int i) {
return [List objectAtIndex:i];
}
int QList::size() {
return [List count];
}
bool QList::isEmpty() {
if ([List count] == 0)
return true;
return false;
}
id QList::takeLast() {
id temp = [List lastObject];
[List removeLastObject];
return temp;
}
id QList::last() {
return [List lastObject];
}
void QList::prepend(id object) {
[List insertObject:object atIndex:0];
}
id QList::takeAt(int i) {
id temp = [List objectAtIndex:i];
[List removeObjectAtIndex:i];
return temp;
}
id QList::takeFirst() {
return takeAt(0);
}
void QList::clear() {
[List removeAllObjects];
}
#endif
I'm recieving EXC_BAD_SIGNAL on this line
return [List count];
Could anyone help me, I much appreciate it, thanks in advance :)
There's no problem with this, the problem was in this line
ai_unit.playerP = this;
I was commenting it out until a later time so I can uncomment it, and it was trying to access that :) Thanks!, if you have advice for this code, let me know :P
Related
I have an application with several Forms. Two of them are quite similar, they have features in the form of VCL objects (labels, images, etc...) in common, which I named the same.
I want to have a function in a specific class which can accept one of these two Form as a parameter in order to modify the parameters that they have in common. The solution I came around does not seem to work.
As my application is quite big and complicated, I replicated the problem using a small example.
First, below is an example of my MainForm :
And an example of one subForm (they are all arranged in a similar way)
I have an additionnal class which is used to fill in the Edits on the subForms. The code for this class is the following:
#pragma hdrstop
#include "master_class.h"
#include "sub_Form2.h"
#include "sub_Form3.h"
#include "sub_Form4.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
Master::Master(void)
{
}
Master::~Master(void)
{
}
void Master::WriteToForm(TForm* Form)
{
TForm2* curForm = static_cast<TForm2*>(Form);
TForm3* self = dynamic_cast<TForm3*>(Form);
TForm2* self2 = dynamic_cast<TForm2*>(Form);
if (self != NULL && self2 == NULL) {
TForm3* curForm = static_cast<TForm3*>(Form);
}
else if (self == NULL && self2 != NULL) {
TForm2* curForm = static_cast<TForm2*>(Form);
}
curForm -> Edit1 -> Text = "blablabla_1";
curForm -> Edit2 -> Text = "blablabla_2";
}
And in the MainForm, the code for the "Fill Form2" button is the following:
Master1 -> WriteToForm(Form2);
where Master1 is just an object of the Master class.
This works very well for Form2 :
But for Form3, which is filled up using Master1 -> WriteToForm(Form3), here is what I get, which the same pb than in my real application:
So what should go to the Edit, is misplaced. I think the main pb comes from the fact that I did not create every label, edit, etc... on the same order. I did that on purpose to mimic my real application. To verify this, I created a 3rd subForm, where this time the VCL objects were created in the same order as my first subForm, and this works:
So I would suspect that this comes from the initial cast
TForm2* curForm = static_cast<TForm2*>(Form);
When I pass Form3 as an argument, Form3 is somewhat casted into the "shape" of Form2, which is not defined in the same order. Maybe this could be corrected by modifying directly the DFM file, but it is not a realistic approach for my main app.
I do this initial cast otherwise I get a compilation error saying that curForm is not known at the first line
curForm -> Edit1 -> Text = "blablabla_1";
So, is there a better way to pass the Form as an argument to the WriteToForm function?
Just because two types are similar does not mean they are related. Your code does not work because your two Form classes are not related to each other in any way. You can't just cast one to the other arbitrarily.
To solve this, you have several options:
code for both Form classes separately, eg:
void Master::WriteToForm(TForm* Form)
{
TForm2* curForm2 = dynamic_cast<TForm2*>(Form);
TForm3* curForm3 = dynamic_cast<TForm3*>(Form);
if (curForm2)
{
curForm2->Edit1->Text = _D("blablabla_1");
curForm2->Edit2->Text = _D("blablabla_2");
}
else if (curForm3)
{
curForm3->Edit1->Text = _D("blablabla_1");
curForm3->Edit2->Text = _D("blablabla_2");
}
}
Or:
void WriteToForm(TForm2* Form);
void WriteToForm(TForm3* Form);
...
void Master::WriteToForm(TForm2* Form)
{
Form->Edit1->Text = _D("blablabla_1");
Form->Edit2->Text = _D("blablabla_2");
}
void Master::WriteToForm(TForm3* Form)
{
Form->Edit1->Text = _D("blablabla_1");
Form->Edit2->Text = _D("blablabla_2");
}
Make your function use a template (however, be aware of this: Why can templates only be implemented in the header file?):
template<typename T>
void WriteToForm(T* Form);
...
void Master::WriteToForm<T>(T* Form)
{
Form->Edit1->Text = _D("blablabla_1");
Form->Edit2->Text = _D("blablabla_2");
}
make the two Form classes derive from a common base class or interface, eg:
class TBaseForm : public TForm
{
public:
inline __fastcall TBaseForm(TComponent *Owner) : TForm(Owner) {}
virtual void SetEdit1(const String &Text) = 0;
virtual void SetEdit2(const String &Text) = 0;
};
...
class TForm2 : public TBaseForm
{
...
public:
__fastcall TForm2(TComponent *Owner);
...
void SetEdit1(const String &NewText);
void SetEdit2(const String &NewText);
};
__fastcall TForm2::TForm2(TComponent *Owner)
: TBaseForm(Owner)
{
...
}
void TForm2::SetEdit1(const String &NewText)
{
Edit1->Text = NewText;
}
void TForm2::SetEdit2(const String &NewText)
{
Edit2->Text = NewText;
}
...
repeat for TForm3...
...
void Master::WriteToForm(TBaseForm* Form)
{
Form->SetEdit1(_D("blablabla_1"));
Form->SetEdit2(_D("blablabla_2"));
}
Or:
__interface INTERFACE_UUID("{E900785E-0151-480F-A33A-1F1452A431D2}")
IMyIntf : public IInterface
{
public:
virtual void SetEdit1(const String &Text) = 0;
virtual void SetEdit2(const String &Text) = 0;
};
...
class TForm2 : public TForm, public IMyIntf
{
...
public:
__fastcall TForm2(TComponent *Owner);
...
void SetEdit1(const String &NewText);
void SetEdit2(const String &NewText);
};
__fastcall TForm2::TForm2(TComponent *Owner)
: TForm(Owner)
{
...
}
void TForm2::SetEdit1(const String &NewText)
{
Edit1->Text = NewText;
}
void TForm2::SetEdit2(const String &NewText)
{
Edit2->Text = NewText;
}
...
repeat for TForm3...
...
void Master::WriteToForm(IMyIntf* Intf)
{
Intf->SetEdit1(_D("blablabla_1"));
Intf->SetEdit2(_D("blablabla_2"));
}
use RTTI to access the fields, eg:
#include <System.Rtti.hpp>
void Master::WriteToForm(TForm* Form)
{
TRttiContext Ctx;
TRttiType *FormType = Ctx.GetType(Form->ClassType());
TRttiField *Field = FormType->GetField(_D("Edit1"));
if (Field)
{
TValue value = Field->GetValue(Form);
if( (!value.Empty) && (value.IsObject()) )
{
TObject *Obj = value.AsObject();
// Either:
static_cast<TEdit*>(Obj)->Text = _D("blablabla_1");
// Or:
TRttiProperty *Prop = Ctx.GetType(Obj->ClassType())->GetProperty(_D("Text"));
if (Prop) Prop->SetValue(Obj, String(_D("blablabla_1")));
}
}
Field = FormType->GetField(_D("Edit2"));
if (Field)
{
TValue value = Field->GetValue(Form);
if( (!value.Empty) && (value.IsObject()) )
{
TObject *Obj = value.AsObject();
// Either:
static_cast<TEdit*>(Obj)->Text = _D("blablabla_2");
// Or:
TRttiProperty *Prop = Ctx.GetType(Obj->ClassType())->GetProperty(_D("Text"));
if (Prop) Prop->SetValue(Obj, String(_D("blablabla_2")));
}
}
}
I am trying to use ephemeral NSURLSessions to provide separate cookie handling for several tasks within my app. These tasks are not directly bound to a UI.
Problem: Whatever I do, the cookieAcceptPolicy of the ephemeral NSHTTPCookieStorage remains NSHTTPCookieAcceptPolicyNever.
Here's my code:
// use a pure in-memory configuration with its own private cache, cookie, and credential store
__block NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
// do anything to accept all cookies
config.HTTPShouldSetCookies = YES;
config.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways;
config.HTTPCookieStorage.cookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways;
__block NSURLSession* session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask* task = [session dataTaskWithURL:[NSURL URLWithString:#"https://test.cgmlife.com/Catalogs"]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPCookieStorage* cookies = session.configuration.HTTPCookieStorage;
NSLog(#"%#", cookies);
NSLog(#"%lu", cookies.cookieAcceptPolicy);
}];
[task resume];
The output from NSLog is always:
Ephemeral <NSHTTPCookieStorage cookies count:0>
1
where 1 is the value for NSHTTPCookieAcceptPolicyNever (expected 0 for NSHTTPCookieAcceptPolicyAlways). The headers in the response are there.
What can I do to have the NSHTTPCookieStorage remember my cookies while the session is alive? I don't need and don't want any persistence. I just want to keep cookies in memory so that they are reused for further requests in the same session.
It looks like ephemeral sessions don't store cookies ever. eskimo1 says on the devforums:
ISTR that ephemeral session configurations don't work the way that
folks expect based on the documentation. I never got around to
looking at this in detail but it seems like you have. You should file
a bug about this; the implementation and documentation are clearly out
of sync, so one of them needs to be fixed.
It looks like the iOS9 ephemeralSessionConfiguration works as expected. On iOS8 though, it seems like the cookie storage returns Never for its policy and it can't be reset. The implementation appears to be no-storage despite the private class name, instead of memory-only.
For iOS8, I was able to substitute a rudimentary implementation though, and it seems to work (at least in the simulator with light testing). Implementing the new methods that take task objects was essential.
#import <Foundation/Foundation.h>
#interface MemoryCookieStorage : NSHTTPCookieStorage
#property (nonatomic, strong) NSMutableArray *internalCookies;
#property (atomic, assign) NSHTTPCookieAcceptPolicy policy;
#end
#implementation MemoryCookieStorage
- (id)init
{
if (self = [super init]) {
_internalCookies = [NSMutableArray new];
_policy = NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
}
return self;
}
- (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy {
return self.policy;
}
- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)cookieAcceptPolicy {
self.policy = cookieAcceptPolicy;
}
- (NSUInteger)_indexOfCookie:(NSHTTPCookie *)target
{
return [_internalCookies indexOfObjectPassingTest:^BOOL(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
return ([target.name caseInsensitiveCompare:cookie.name] == NSOrderedSame &&
[target.domain caseInsensitiveCompare:cookie.domain] == NSOrderedSame &&
(target.path == cookie.path || [target.path isEqual:cookie.path]));
}];
}
- (void)setCookie:(NSHTTPCookie *)cookie
{
if (self.cookieAcceptPolicy != NSHTTPCookieAcceptPolicyNever)
{
#synchronized(_internalCookies) {
NSInteger idx = [self _indexOfCookie:cookie];
if (idx == NSNotFound)
[_internalCookies addObject:cookie];
else
[_internalCookies replaceObjectAtIndex:idx withObject:cookie];
}
}
}
- (void)deleteCookie:(NSHTTPCookie *)cookie
{
#synchronized(_internalCookies) {
NSInteger idx = [self _indexOfCookie:cookie];
if (idx != NSNotFound)
[_internalCookies removeObjectAtIndex:idx];
}
}
- (NSArray *)cookies
{
#synchronized(_internalCookies) {
return [_internalCookies copy];
}
}
static BOOL HasCaseSuffix(NSString *string, NSString *suffix)
{
return [string rangeOfString:suffix options:NSCaseInsensitiveSearch|NSAnchoredSearch|NSBackwardsSearch].length > 0;
}
static BOOL IsDomainOK(NSString *cookieDomain, NSString *host)
{
return ([cookieDomain caseInsensitiveCompare:host] == NSOrderedSame ||
([cookieDomain hasPrefix:#"."] && HasCaseSuffix(host, cookieDomain)) ||
(cookieDomain && HasCaseSuffix(host, [#"." stringByAppendingString:cookieDomain])));
}
- (NSArray *)cookiesForURL:(NSURL *)URL
{
NSMutableArray *array = [NSMutableArray new];
NSString *host = URL.host;
NSString *path = URL.path;
#synchronized(_internalCookies)
{
for (NSHTTPCookie *cookie in _internalCookies)
{
if (!IsDomainOK(cookie.domain, host))
continue;
BOOL pathOK = cookie.path.length == 0 || [cookie.path isEqual:#"/"] || [path hasPrefix:cookie.path];
if (!pathOK)
continue;
if (cookie.isSecure && [URL.scheme caseInsensitiveCompare:#"https"] != NSOrderedSame)
continue;
if ([cookie.expiresDate timeIntervalSinceNow] > 0)
continue;
[array addObject:cookie];
}
}
array = (id)[array sortedArrayUsingComparator:^NSComparisonResult(NSHTTPCookie *c1, NSHTTPCookie *c2) {
/* More specific cookies, i.e. matching the longest portion of the path, come first */
NSInteger path1 = c1.path.length;
NSInteger path2 = c2.path.length;
if (path1 > path2)
return NSOrderedAscending;
if (path2 > path1)
return NSOrderedDescending;
return [c1.name caseInsensitiveCompare:c2.name];
}];
return array;
}
- (NSArray *)sortedCookiesUsingDescriptors:(NSArray *)sortOrder
{
return [[self cookies] sortedArrayUsingDescriptors:sortOrder];
}
- (void)getCookiesForTask:(NSURLSessionTask *)task completionHandler:(void (^) (NSArray *taskCookies))completionHandler
{
NSArray *urlCookies = [self cookiesForURL:task.currentRequest.URL];
completionHandler(urlCookies);
}
- (void)setCookies:(NSArray *)newCookies forURL:(NSURL *)URL mainDocumentURL:(NSURL *)mainDocumentURL
{
NSString *host = mainDocumentURL.host;
for (NSHTTPCookie *cookie in newCookies)
{
switch (self.cookieAcceptPolicy)
{
case NSHTTPCookieAcceptPolicyAlways:
[self setCookie:cookie];
break;
case NSHTTPCookieAcceptPolicyNever:
break;
case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
if (IsDomainOK(cookie.domain, host))
[self setCookie:cookie];
break;
}
}
}
- (void)storeCookies:(NSArray *)taskCookies forTask:(NSURLSessionTask *)task
{
NSURL *mainURL = task.currentRequest.mainDocumentURL ?: task.originalRequest.mainDocumentURL ?: task.originalRequest.URL;
[self setCookies:taskCookies forURL:task.currentRequest.URL mainDocumentURL:mainURL];
}
#end
It should be possible to test sessionConfiguration.HTTPCookieStorage.cookieAcceptPolicy == NSHTTPCookieAcceptPolicyNever after creating the ephemeral session to see if the HTTPCookieStorage needs to be replaced with an instance of the above class (shouldn't need it on iOS9). There are probably some bugs... I just needed this for a demo and it worked well enough for that. But they shouldn't be too hard to fix if any come up.
In my app i have a C++ class and an Objective-c class working together the following way:
PingPong.h
#ifndef __RSSCPPCallbackTest__PingPong__h
#define __RSSCPPCallbackTest__PingPong__h
#include <iostream>
class PingPong
{
public:
static void requestPingPongWithText(std::string text);
static void eventRequestPingPongWithTextSuccess(std::string successString);
static void eventRequestPingPongWithTextFailure(std::string failureString);
};
#endif
PingPong.cpp
#ifndef __RSSCPPCallbackTest__PingPong__m
#define __RSSCPPCallbackTest__PingPong__m
#include "PingPong.h"
void PingPong::requestPingPongWithText(std::string text)
{
if (text.compare("ping") == 0)
{
PingPong::eventRequestPingPongWithTextSuccess("success ping");
}
else
{
PingPong::eventRequestPingPongWithTextFailure("failure pong");
}
}
#endif
Objective-C class: MainViewController.mm
#implementation MainViewController
/* init, viewDidLoad, etc... */
// Call ping with a button
- (IBAction)sayPing:(id)sender {
NSString *text = #"ping";
PingPong::requestPingPongWithText([text UTF8String]);
}
// Call pong with another button
- (IBAction)sayPong:(id)sender {
NSString *text = #"pong";
PingPong::requestPingPongWithText([text UTF8String]);
}
#end
void PingPong::eventRequestPingPongWithTextSuccess(std::string successString)
{
NSLog(#"successString: %#", [NSString stringWithCString:successString.c_str()
encoding:[NSString defaultCStringEncoding]]);
}
void PingPong::eventRequestPingPongWithTextFailure(std::string failureString)
{
NSLog(#"failureString: %#", [NSString stringWithCString:failureString.c_str()
encoding:[NSString defaultCStringEncoding]]);
}
This works fine. What i would like to do finally is to wrap this into a function with a completion block looking like:
[self requestPingPongWithText: text
completion:^(NSString *successString, NSString *failureString)) completion {
if (successString) {
NSLog(#"successString: %#", successString); }
else if (failureString) {
NSLog(#"failureString: %#", failureString); }
}];
How can i wrap up my existing code to have a function looking like above?
Lets make a new typdef in PingPong.h:
typedef void (^OnComplete)(std::string successString, std::string failureString);
Make a new method for the request by block:
static void requestPingPongWithBlock(std:string text, OnComplete block);
another way, to make it explicit:
static void requestPingPongWithBlock(std:string text, void (^block)(std::string successString, std::string failureString));
implementation in PingPong.cpp:
void PingPong::requestPingPongWithBlock(std::string text, OnComplete block)
{
if (text.compare("ping") == 0)
{
block("success ping", "");
}
else
{
block("", "failure pong");
}
}
in MainViewController.mm
-(void)requestPingPongWithText:(NSString*)text completion:(OnComplete) compblock{
PingPong::requestPingPongWithBlock([text UTF8String],compblock);
}
and you can call it like this way:
[self requestPingPongWithText: text
completion:^(std::string successString, std::string failureString) {
if (successString.length() != 0) {
NSLog([NSString stringWithUTF8String: successString.c_str()]); }
else if (failureString.length() != 0) {
NSLog([NSString stringWithUTF8String: failureString.c_str()]); }
}];
I hope it was helpful ;)
I need to increment an integer.I have this code here :
Utils.h :
class Utils{
static HUD* hudLayer();
static Layer* layerWithTag(int tag);
};
Utils.cpp :
HUD* Utils::hudLayer(){
return (HUD*)Utils::layerWithTag(TAG_HUD);
}
Layer* Utils::layerWithTag(int tag)
{
Scene *sc = Director::getInstance()->getRunningScene();
if (sc->getTag() == TAG_GAME_SCENE) {
Layer *layer = (Layer *)sc->getChildByTag(tag);
return layer;
}
return NULL;
}
HUD.h
class HUD : public Layer{
public:
int score1;
Label* scoreLabel1;
virtual bool init();
void didScore();
CREATE_FUNC(HUD);
};
HUD.cpp :
bool HUD::init(){
if(!Layer::init()){return false;}
score1 = 0;
scoreLabel1 = Label::createWithSystemFont(CCString::createWithFormat("Score : %d",score1)->getCString(), “Arial“, 64);
scoreLabel1->setAnchorPoint(Point(0.0f, 1.0f));
scoreLabel1->setPosition(Point(20, Utils::s().height-10));
this->addChild(scoreLabel1);
return true;
}
void HUD::didScore(){
score1+=10; // Error HERE after coming from onTouchBegan (says parentis null)
scoreLabel1->setString(CCString::createWithFormat("Score : %d",score1)->getCString());
}
In GameScene.h now i have this in onTouchBegan method :
bool GameScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
Point location = touch->getLocationInView();
location = Director::getInstance()->convertToGL(location);
if(location.x < 300.0f){
Utils::hudLayer()->didScore();
}
return true;
}
What am i doing wrong here ?
I can increment an integer in V 2.x the same way but not in V 3.0 . WHY ?
In cocos2d-x v3 is a new listener system for events (touches, accelerometr etc.), you need to create listener for getting touches. In GameScene::init you should put something like that
auto listener1 = EventListenerTouchOneByOne::create();
listener1->setSwallowTouches(true);
listener1->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener1, this);
Look at:
http://www.cocos2d-x.org/wiki/EventDispatcher_Mechanism
In my application I am displaying contacts in table view with indexed list. I am displaying indexed list as follow:
static NSString *letters = #"abcdefghijklmnopqrstuvwxyz#";
-(void)getAllUserInfoUsingBlock:(lclResultsArray) block
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSMutableArray *allUserInfoArray = [[NSMutableArray alloc]init];
NSLog(#"[letters length]:- %d",[letters length]);
for (int i = 0; i < [letters length]; i++ ) {
NSMutableDictionary *row = [[NSMutableDictionary alloc] init];
char currentLetter[2] = { toupper([letters characterAtIndex:i]), '\0'};
NSString *str=[NSString stringWithCString:currentLetter encoding:NSASCIIStringEncoding];
NSMutableArray *words = nil;
NSLog(#"Value of i:- %d:: Letter:- %#",i,str);
if (i<[letters length]) {
words = [self getUserInfoByStartingCharOfLastName:str isForEmptyValue:NO];
}
else {
// Get users where name is empty
words = [self getUserInfoByStartingCharOfLastName:#"" isForEmptyValue:YES];
}
NSLog(#"Count for %# :- %d",str,words.count);
[row setValue:str forKey:#"sectionTitle"];
[row setValue:words forKey:#"sectionRows"];
[allUserInfoArray addObject:row];
}
dispatch_async(dispatch_get_main_queue(), ^{
for (NSDictionary *dict in allUserInfoArray) {
NSLog(#"Array count:- %d",[[dict objectForKey:#"sectionRows"]count]);
}
block(allUserInfoArray,nil);
});
});
}
- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section
{
if (aTableView != self.searchDisplayController.searchResultsTableView){
NSMutableDictionary *sections=[self.contactsArray objectAtIndex:section];
NSString * sectionTitle= [sections objectForKey:#"sectionTitle"];
return sectionTitle;
}
return nil;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
if (tableView != self.searchDisplayController.searchResultsTableView){
NSMutableDictionary *sections=[self.contactsArray objectAtIndex:index];
NSString * sectionTitle= [sections objectForKey:#"sectionTitle"];
return [self.indices indexOfObject:sectionTitle];
}
return 0;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if (tableView != self.searchDisplayController.searchResultsTableView){
return [self.contactsArray valueForKey:#"sectionTitle"];
}
return nil;
}
But it displays as shown in following images
As you can see in first image its displaying A.C.E .... V.X.Z# Its displaying alternate dots(.) after every character.But as shown in second image its dispalying correct headet title for table from ABC....XYZ#
Whats wrong in my implementation ?
Alternative dots between characters in indexed list depends upon display height of that indexedlist.if we can increase the tableSize .it will be automatically display whole characters.