I have data to generate report that have header footer and content.
In the content have many group when the data in each group over the page area it add new page and write header of group and continued content data
Where can I have lib. or something to do this Task ??
Thanks For Advance.
Add for request code
NSArray *headObject = [uniqueStates allObjects];////Store head of each group
NSArray *detail; //Store all of data to present in table
int allData = [detail count]; // Tel amount of all data to show
/*
int headGroupline = 1; //Tel amount of head group line
int footGroupline = 1; //Tel amount of foot group line
*/
int detailIndex = 0; ///Tel what line we are now
int detailHeadIndex = 0; ///Tel what group we are now
int subdetail = 0; // Tel what line on group now
int aviableLineInpage = 24; // Line avilable in page for data to show
int allPage = 0; //Sum of all page
for (; detailIndex < allData; ) {
allPage++;
for (int i=0; i < aviableLineInpage;) {
if (allData - detailIndex == 0) {
///ShowgrandTotal
........
detailIndex++;
i+=25;
}else{
if (i == 0) {
//Show Head Group
......
}else{
if (subdetail == [[detail filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(buy_date == %#)", headObject[detailHeadIndex]]] count]+1) {
detailHeadIndex++;
//Show Head Group
..........
}else{
if (subdetail == [[detail filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(buy_date == %#)", headObject[detailHeadIndex]]] count]) {
//Show sum of each group
..........
i++;
detailIndex++;
subdetail++;
detailHeadIndex++;
}else{
//Show data of detail
........................
detailIndex++;
subdetail++;
}
}
}
i++;
}
}//for all line in page
}//for allData
It format is:
date 27/01/2014
data1
data2
data3
sum date 27/01/2014
date 28/01/2014
data1
data2
<============if page brake add new page and
date 28/01/2014
data3
sum date 28/01/2014
grand total........
But it goes
date 27/01/2014
data1
data2
data3
sum date 27/01/2014
data1
data2
<============if page brake add new page and
date 28/01/2014
data3
grand total........
Thanks very much
Use CGPDFDocumentRef and the associated functions to create the PDF document and each page it contains. When you create a page (UIGraphicsBeginPDFPageWithInfo) you can get the associated drawing context (UIGraphicsGetCurrentContext). Once you have that you can draw in a number of ways:
You could create a view with your header and footer, add content and render it into the view (using its layer)
You could draw images and text direct into the context (using CoreText (CTFrameDraw))
You need to create the logic to set how much content can fit on any one page and when you need to create a new page.
Also, depending on how you choose to draw content into the context you may need to scale and transform (CGContextScaleCTM + CGContextTranslateCTM) the context so that your content isn't upside down.
See this Apple guide.
int allData = [detail count]; // Tel amount of all data to show
/*
int headGroupline = 1; //Tel amount of head group line
int footGroupline = 1; //Tel amount of foot group line
*/
int detailIndex = 0; ///Tel what line we are now
int detailHeadIndex = 0; ///Tel what group we are now
int subdetail = 0; // Tel what line on group now
int aviableLineInpage = 24; // Line avilable in page for data to show
int allPage = 0; //Sum of all page
for (; detailIndex < allData; ) {
allPage++;
for (int i=0; i < aviableLineInpage;) {
if (allData - detailIndex == 0) {
detailIndex++;
i+=25;
}else{
if (i == 0) {
if (subdetail == -1) {
subdetail = 0;
}
}else{
if (subdetail == -1) {
subdetail = 0;
}else{
if (subdetail == [[detail filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(buy_date == %#)", headObject[detailHeadIndex]]] count]) {
i++;
subdetail = -1;
detailHeadIndex++;
if (detailHeadIndex == [headObject count] ) {
detailIndex++;
}
}else{
detailIndex++;
subdetail++;
}
}
}
i++;
}
}//for all line in page
}//for allData
Related
How to deal with or handle/avoid the array out of range error here :
for(int i=0; i<=ObjectsTotal()-1; i++)
{
string objName = ObjectName(0,i);
if(StringFind(objName,"Last#")>=0)
{
string tempval= objName;
string temtext= ObjectGetString(0,objName,OBJPROP_TEXT);
StringReplace(tempval,"Last#","");
int tempnum = (int)(tempval);
for(int k=tempnum; k>=tempnum-20; k--)
{
if(
RBuffer1[k] != EMPTY_VALUE)
{
ObjectDelete(0,objName);
DrawText("Last#"+tempnum,Time[tempnum],Low[tempnum],temtext+"_0","Arial",9,clrWhite);
break;
}
else
if(RBuffer2[k] != EMPTY_VALUE)
{
ObjectDelete(0,objName);
DrawText("Last#"+tempnum,Time[tempnum],Low[tempnum],temtext+"_1","Arial",9,clrWhite);
break;
}
}
}
}
I am sure there is something wrong with my logic but cant figure out what exactly , and the indicator works fine on some timeframes but on 2 ,3 timeframes it throws the error array out of range
This is for(int k=tempnum; k>=tempnum-20; k--) where I am receiving the error.
First of all, check the size of "RBuffer1" using "ArraySize":
int iArrSize = ArraySize(RBuffer1);
if (iArrSize >= 20)
{
...
}
more importantly, the array index starts from 0 up to the predefined size (in your case 20 or 21). But you are trying to access the index 20 up to 41. Obviously, you will receive an "Array out of range" error message. Just change your code to something like:
if (RBuffer1[k - 21] != EMPTY_VALUE)
{
...
}
I wrote the following program. The swap is working fine if i debug it. However i am not able to return the complete linked list. It is changing the head as well. what is wrong?
public static Node<Integer> swapElementsAtiAndj(Node<Integer> head, int i, int j)
{
Node<Integer> temp= head;
Node<Integer> prev1 = temp;
Node<Integer> prev2 = temp;
Node<Integer> toSwap1 = temp;
Node<Integer> toSwap2 = temp;
int count =0;
int pos1 =i;
int pos2 =j;
if(i>j) {
pos1 = j;
pos2 =i;
}
while (count !=pos1) {
prev1 = toSwap1;
toSwap1 = toSwap1.next;
prev2 = prev1;
toSwap2 = toSwap1;
count++;
}
while(count != pos2) {
prev2 = toSwap2;
toSwap2 = toSwap2.next;
count++;
}
temp.data = toSwap1.data;
temp.next = toSwap2.next;
toSwap2.next = toSwap1.next;
prev2.next = temp;
prev1.next = toSwap2;
return head;
}
Yes, your head is getting modified at
temp.next = toSwap2.next;
Because temp is pointing at head. Here is how you can fix it:
First of all,
prev2 = prev1;
toSwap2 = toSwap1;
can be written outside of while loop.
Now, after second while loop toSwap1 and toSwap2 are pointing at elements to be swapped.
// Swap prev
prev1.next = toSwap2;
prev2.next = toSwap1;
// Store toSwap2's next in temp
temp = toSwap2.next;
// Set toSwap2's next to toSwap1's next
toSwap2.next = toSwap1.next;
// Set toSwap1's next to old toSwap2's next (i.e temp)
toSwap1.next = temp;
// Return
return head;
I currently have a single player board game with one human player and three AI players. I would like to change that to four human players. How can I achieve that from the code below? Can I simply use and OR statement for the 1st line "currentplayer ==3" and have that read "currentplayer == 3 | 1"
if (currentPlayer == 3 && ([currentTokens count])){
for (int count = 0; count < [currentTokens count]; count++) {
Token *token = (Token*)[currentTokens objectAtIndex:count];
[token setUserInteractionEnabled:YES];
}
}
else if ([currentTokens count])//For NonHuman Players
{
// NSLog(#"Break3.3");
int arrLength = [currentTokens count];
// NSLog(#"Break3.4 and %i",arrLength);
////////////////// AI for NON HUMAN AT OCCURENCE OF SIX OF DICE////////////
Token *nonHumanToken;
int tokenAtHomeCount = 0;
if (firstDiceValue == 6) {
for (int count = 0; count < [currentTokens count]; count++) {
Token *selectedToken = (Token*)[currentTokens objectAtIndex:count];
if (selectedToken.isAtHome) {
tokenAtHomeCount++;
nonHumanToken = (Token*)[currentTokens objectAtIndex:count];
break;
}
}
if (!tokenAtHomeCount) {
nonHumanToken = (Token*)[currentTokens objectAtIndex:(arc4random()%arrLength)];
}
}
else{
nonHumanToken = (Token*)[currentTokens objectAtIndex:(arc4random()%arrLength)];
}
////////////////////////////////
[self performSelector:#selector(courseOfActionWithDelay:) withObject:nonHumanToken afterDelay:1.5];
// [self moveToken:nonHumanToken Till:firstDiceValue];
if ([currentTokens count]) {
[self DisplayMessageForMovingTokens:currentPlayer];
}
}
Ideally if you are replacing your AI with human players, you would completely ditch the AI code. I would look into duplicating the human code for each player.
Say you have:
if(player==1) {
player 1's turn stuff here
}
you would expand off of that and move on to:
if(player==2) {
player 2's turn stuff here
}
If this is to be a turn based game, instead of tracking players, track turns. Turn one would be player one, turn two is player two, and then just reset once you get to the max number of players for the round.
I am getting the error out of range object[,]
string MissingCompanies="";
List<string> cmp = new List<string>();
cmp = sr.CompanyCode();
int count=0;
if (DataRange!=null)
{
while (DataRange != null)
{
string code;
bool match;
match = false;
code = cmp[count]; //getting error here**
for (int dr = 1; dr <= DataRange.GetUpperBound(0); dr++)
{
if (code.Equals(DataRange[dr, 1]))
{
match = true;
break;
}
}
count++;
if (!match)
{
MissingCompanies = MissingCompanies + "," + code;
}
I'm getting error: code=cmp[count] -- index has out of range.
I'd be grateful for any help with this.
Sorry for the somewhat generic title, if anyone has a better suggestion please let me know.
Basically I am writing a custom leaderboard view whereby I want to show 3 scores only. If possible it will show the current user's score in the middle but, if the user is at the top or the bottom of the list, it should still show 3 scores but itll show another users above or below the list.
e.g.
Me (If I am top, then show 2 below)
User 1
User 2
or
User 1
Me (usual case where I am in the middle of two scores)
User 2
or
User 1
User 2
Me (If I am bottom show two scores above me)
I have a function written that does the first part of this but doesnt take into account edge cases which is what I am struggling with. Can anyone please advise?
-(void)getNearbyScores:(int)score{
GCLeaderboardScore *closestScoreAbove = nil; //Custom container for GC properties
GCLeaderboardScore *closestScoreBelow = nil; //Contains playerID, score, alias etc
if ([playerScores count] == 0){ //playerScores is an NSMutableDictionary
return;
}
for (NSString* key in playerScores) {
GCLeaderboardScore *playerScore = (GCLeaderboardScore *)[playerScores objectForKey:key];
if ((closestScoreAbove == nil || closestScoreAbove->score > playerScore->score) && playerScore->score > score){
closestScoreAbove = playerScore;
}
else if ((closestScoreBelow == nil || closestScoreAbove->score < playerScore->score) && playerScore->score < score){
closestScoreBelow = playerScore;
}
}
me->score = score;
me->rank = 1;
if (closestScoreAbove != nil) {
me->rank = closestScoreAbove->rank + 1;
nearbyScores = [NSMutableArray arrayWithObjects: closestScoreAbove, me, closestScoreBelow, nil];
}
else {
nearbyScores = [NSMutableArray arrayWithObjects: me, closestScoreBelow, nil];
}
}
Assuming there is a me GCLeaderboardScore object, the method below should return an array with the desired GCLeaderboardScore objects (untested):
-(NSArray *)getNearbyScores {
if(playerScores.count==0) return nil;
// Create an array sorted by score
NSArray *sortedByScore=[playerScores sortedArrayUsingComparator: ^(id object1, id object2) {
GCLeaderboardScore *score1=object1;
GCLeaderboardScore *score2=object2;
if(score1->score < score2->score) return NSOrderedAscending;
if(score1->score > score2->score) return NSOrderedDescending;
return NSOrderedSame;
}];
// Find index of me
NSUInteger idx=[sortedByScore indexOfObject:me];
// If me not found, return nil
if(idx==NSNotFound) return nil;
// Ideally we want to show the player before and behind
idx=MAX(0,(NSInteger)idx-1);
// maxIdx will be idx+2 or index of last object if lower
NSUInteger maxIdx=MIN(sortedByScore.count-1,idx+2);
// In case we are last, show two previous results (if array large enough)
if (maxIdx > 3)
idx=MAX(0,maxIdx-3);
// And return the objects, may be 1..3 objects
return [sortedByScore subarrayWithRange:NSMakeRange(idx,maxIdx-idx+1)];
}
I assume you have an array of scores. (Actual implementation can be adapted to your code)
Initialize:
firstScoreAbove = VERY_LARGE_SCORE; secondScoreAbove = VERY_LARGE_SCORE + 1;
firstScoreBelow = -1; secondScoreBelow = -2;
Scan the array elements.
if ( newScore > myScore ) {
if ( newScore < firstScoreAbove ) {
secondScoreAbove = firstScoreAbove;
firstScoreAbove = newScore;
} else if ( newScore < secondScoreAbove ) {
secondScoreAbove = newScore;
}
} else {
// similarly for below.
}
After scanning,
If firstScoreAbove has not changed, then myScore is top and output the two below scores.
If firstScoreBelow has not changed, then myScore is lowest and output the two above scores.
Else Output firstScoreAbove, myScore, firstScoreBelow.