MutableAttributedString concatenation - nsstring

I have tried to concatenate to attributed string with different properties,But not reflecting any changes,Here my code
//White color
NSMutableAttributedString *attributedString2 = [[NSMutableAttributedString alloc] initWithData:[[NSString stringWithFormat:#"%#",readingPartCntnt] dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
[attributedString2 addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, attributedString2.length)];
[attributedString2 addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, attributedString2.length)];
//Blue color
NSMutableAttributedString *attributedString3 = [[NSMutableAttributedString alloc] initWithData:[[NSString stringWithFormat:#"%#",readingFootCntnt] dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
[attributedString3 addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:(154.0/255.0) green:(224.0/255.0) blue:(250.0/255.0) alpha:1.0] range:NSMakeRange(0, attributedString3.length)];
[attributedString3 addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, attributedString3.length)];
//UITextview
readingContent.attributedText = [NSMutableAttributedString attributedStringWithAttachment:attributedString2,attributedString3];
I want to concatenate both attributedString2 attributedString3 into readingContent.What change required in my code?Please help me to resolve

Related

How to use OCMock to return different result base on different argument

I am trying to mock different method return when passing different argument for the same method.
self.myMock = [OCMockObject mockForClass:[MyClass class]];
[[[self.myMock expect] andReturnValue:5] myStaticMethod:3];
[[[self.myMock expect] andReturnValue:10] myStaticMethod:6];
But it only takes the first one, when argument is 3 then return 5, and when argument is 6, it return nil instead of 10. Does anyone know whether is a way to test this?
the real code:
-(NSMutableArray*)convertChildStringToChildDic:(NSString*)strchildren
{
NSArray *kididarray = [strchildren componentsSeparatedByString:#","];
//处理小孩信息
/*children = (
{
avatarSmall = "<null>";
currentStatus = 0;
displayName = stu1;
"id_str" = "70938032-3811-e411-946a-005056c00008";
title = Child;
}
)*/
NSMutableArray *rstchildarray = [NSMutableArray arrayWithCapacity:1];
for (NSString *enrollment_id in kididarray) {
if (enrollment_id.length <= 0) {
continue;
}
**NSMutableDictionary *mdic = [[RoomInfoManager sharedManager] getKidDictionaryByID:enrollment_id];**
[mdic setValue:enrollment_id forKey:#"id_str"];
if (mdic != nil) {
[rstchildarray addObject:mdic];
}
}
return rstchildarray;
}
Test:
-(void) testconvertChildStringToChildDic_InvalidAgruments {
NSMutableDictionary *childdic = [[NSMutableDictionary alloc] init];
childdic[#"id"] = #"josh";
NSMutableDictionary *childdic1 = [[NSMutableDictionary alloc] init];
childdic1[#"id"] = #"joy";
id mockRIM = OCMClassMock([RoomInfoManager class]);
**OCMStub([mockRIM getKidDictionaryByID:#"josh"]).andReturn(childdic);
**OCMStub([mockRIM getKidDictionaryByID:#"joy"]).andReturn(childdic1);****
RoomInfoManager *roomInfoMgr = [RoomInfoManager alloc];
id mockPartialRIM = OCMPartialMock(roomInfoMgr);
OCMExpect([mockPartialRIM sharedManager]).andReturn(mockRIM); // use expect
NSString *childStr = #"josh,joy";
NSMutableArray *childarray = [[ReportOperator alloc] convertChildStringToChildDic:childStr];
NSDictionary *childrenArraydic = #{#"id" : #"josh", #"id_str": #"josh"};
NSMutableArray *resultArray = [NSMutableArray arrayWithObjects:childrenArraydic, nil];
[mockPartialRIM verify]; // verify expect,验证该对像是否被调用。
XCTAssertEqualObjects(childarray, resultArray);
}
the second call
OCMStub([mockRIM getKidDictionaryByID:#"joy"]).andReturn(childdic1);
does not seem take effect and return nil instead.

ios NSAttributedString firstLineHeadIndent bug

I try to use FirstLineHeadIndent,but when i use, The string will be truncated.
NSString *string = #"hello,i am aaa,123456 my name is";
UIFont *textFont = [UIFont systemFontOfSize:15];
self.textView = [UILabel new];
_textView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_textView];
_textView.numberOfLines = 0;
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineHeightMultiple = 1.4;
[paragraphStyle setLineSpacing:4];
[paragraphStyle setFirstLineHeadIndent:30];
[paragraphStyle setAlignment:NSTextAlignmentJustified];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:string attributes:#{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:textFont,NSForegroundColorAttributeName:[UIColor darkGrayColor]}];
[_textView setAttributedText:string];
The results of the intercept is hello,i am aaa,123456 my.
about the first line retract, am i wrong? thanks!

dateByAddingComponents method error

Using NSCalendar and its method dateByAddingComponents:toDate:options: the method sometimes return a wrong value. For instante:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:2013];
[components setMonth:2];
[components setDay:27];
NSDate *date = [calendar dateFromComponents:components];
NSLog(#"%#", date); // 2013-02-27
NSDateComponents *addingComponents = [[NSDateComponents alloc] init];
[addingComponents setMonth:1];
[addingComponents setDay:4]; // value 5 give the same result.
date = [calendar dateByAddingComponents:addingComponents toDate:date options:0];
NSLog(#"%#", date); // 2013-03-31
The console log: 2013-02-27 and 2013-03-31.
Now, if a change the day component value to 5, the method return the same NSDate, but if a change to 6, the date if 2013-04-01.
Anyone has an answer for this behavior? Thanks on advance.
Rafael Cruz Márquez.

UILabel detect line breaks

I am currently using a UILabel to display multiple lines of text. The line break most is set to NSLineBreakByWordWrapping so the the label automatically inserts line breaks. How can I detect where those line breaks are? Basically, I want to return a string with each \n break included.
Here is my work around for detecting line breaks inside UILabel
- (int)getLengthForString:(NSString *)str fromFrame:(CGRect)frame withFont:(UIFont *)font
{
int length = 1;
int lastSpace = 1;
NSString *cutText = [str substringToIndex:length];
CGSize textSize = [cutText sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, frame.size.height + 500)];
while (textSize.height <= frame.size.height)
{
NSRange range = NSMakeRange (length, 1);
if ([[str substringWithRange:range] isEqualToString:#" "])
{
lastSpace = length;
}
length++;
cutText = [str substringToIndex:length];
textSize = [cutText sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, frame.size.height + 500)];
}
return lastSpace;
}
-(NSString*) getLinebreaksWithString:(NSString*)labelText forWidth:(CGFloat)lblWidth forPoint:(CGPoint)point
{
//Create Label
UILabel *label = [[UILabel alloc] init];
label.text = labelText;
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
//Set frame according to string
CGSize size = [label.text sizeWithFont:label.font
constrainedToSize:CGSizeMake(lblWidth, MAXFLOAT)
lineBreakMode:UILineBreakModeWordWrap];
[label setFrame:CGRectMake(point.x , point.y , size.width , size.height)];
//Add Label in current view
[self.view addSubview:label];
//Count the total number of lines for the Label which has NSLineBreakByWordWrapping line break mode
int numLines = (int)(label.frame.size.height/label.font.leading);
//Getting and dumping lines from text set on the Label
NSMutableArray *allLines = [[NSMutableArray alloc] init];
BOOL shouldLoop = YES;
while (shouldLoop)
{
//Getting length of the string from rect with font
int length = [self getLengthForString:labelText fromFrame:CGRectMake(point.x, point.y, size.width, size.height/numLines) withFont:label.font] + 1;
[allLines addObject:[labelText substringToIndex:length]];
labelText = [labelText substringFromIndex:length];
if(labelText.length<length)
shouldLoop = NO;
}
[allLines addObject:labelText];
//NSLog(#"\n\n%#\n",allLines);
return [allLines componentsJoinedByString:#"\n"];
}
How to use
NSString *labelText = #"We are what our thoughts have made us; so take care about what you think. Words are secondary. Thoughts live; they travel far.";
NSString *stringWithLineBreakChar = [self getLinebreaksWithString:labelText forWidth:200 forPoint:CGPointMake(15, 15)];
NSLog(#"\n\n%#",stringWithLineBreakChar);
You just need to set parameters required by getLinebreaksWithString and you will get a string with each "\n" break included.
OutPut
Here is my solution to this problem.
I iterate through all whitespace characters in the provided string, set substrings (from beginning to current whitespace) to my label and check the difference in the height. When the height changes I insert a new line character (simulates a line break).
func wordWrapFormattedStringFor(string: String) -> String {
// Save label state
let labelHidden = label.isHidden
let labelText = label.text
// Set text to current label and size it to fit the content
label.isHidden = true
label.text = string
label.sizeToFit()
label.layoutIfNeeded()
// Prepare array with indexes of all whitespace characters
let whitespaceIndexes: [String.Index] = {
let whitespacesSet = CharacterSet.whitespacesAndNewlines
var indexes: [String.Index] = []
string.unicodeScalars.enumerated().forEach { i, unicodeScalar in
if whitespacesSet.contains(unicodeScalar) {
let index = string.index(string.startIndex, offsetBy: i)
indexes.append(index)
}
}
// We want also the index after the last character so that when we make substrings later we include also the last word
// This index can only be used for substring to this index (not from or including, since it points to \0)
let index = string.index(string.startIndex, offsetBy: string.characters.count)
indexes.append(index)
return indexes
}()
var reformattedString = ""
let boundingSize = CGSize(width: label.bounds.width, height: CGFloat.greatestFiniteMagnitude)
let attributes = [NSFontAttributeName: font]
var runningHeight: CGFloat?
var previousIndex: String.Index?
whitespaceIndexes.forEach { index in
let string = string.substring(to: index)
let stringHeight = string.boundingRect(with: boundingSize, options: .usesLineFragmentOrigin, attributes: attributes, context: nil).height
var newString: String = {
if let previousIndex = previousIndex {
return string.substring(from: previousIndex)
} else {
return string
}
}()
if runningHeight == nil {
runningHeight = stringHeight
}
if runningHeight! < stringHeight {
// Check that we can create a new index with offset of 1 and that newString does not contain only a whitespace (for example if there are multiple consecutive whitespaces)
if newString.characters.count > 1 {
let splitIndex = newString.index(newString.startIndex, offsetBy: 1)
// Insert a new line between the whitespace and rest of the string
newString.insert("\n", at: splitIndex)
}
}
reformattedString += newString
runningHeight = stringHeight
previousIndex = index
}
// Restore label
label.text = labelText
label.isHidden = labelHidden
return reformattedString
}
Image - Comparison of output string with label text.
This solution worked really well in my case, hope it helps.

Solution for Paypal Error 589023 in iphone application

This is the Resolution for Paypal (Sandbox) Error "589023" in iPhone Application
-(void)payWithPayPal{
for (int i=0;i
PayPal *payPal=[PayPal getPayPalInst];
payPal.shippingEnabled = FALSE;
payPal.dynamicAmountUpdateEnabled = NO;
payPal.feePayer = FEEPAYER_EACHRECEIVER;
PayPalPayment *payment = [[[PayPalPayment alloc] init] autorelease];
payment.recipient = #"UKMCA2010#GMAIL.COM";
payment.paymentCurrency = #"USD";
payment.description = #"Payment Discription here...";
SampleSingleton *sample=[SampleSingleton sharedInstance];
payment.merchantName =[sample getStrRestaurantName];
payment.invoiceData = [[[PayPalInvoiceData alloc] init] autorelease];
payment.invoiceData.invoiceItems = [NSMutableArray array];
PayPalInvoiceItem *item = [[PayPalInvoiceItem alloc] init];
item.totalPrice=[NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%.2f", 126.34545]]; // If u give xxx.xx , no need to give the %.2f , u can give directly %f
item.name = objTempReceived.strItemName;
item.itemId = #"Item ID";
[payment.invoiceData.invoiceItems addObject:item];
[item release];
}
payment.subTotal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%.2f",126.34545]]; //Total and Subtotal must be equal
payment.invoiceData.totalTax = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%.2f",3.34]];
NSLog(#"Total Tax is :%#",[payment.invoiceData.totalTax stringValue]);
[payPal checkoutWithPayment:payment];
}
Here the total and subtotal and Tax allows only two digits after the .(dot) Ex: (234.xx). So by using the %.2f to work perfectly.

Resources