为UITextView添加轮廓/描边

7
我想在用户输入时,为可编辑的UITextView文本添加轮廓或描边,就像meme一样:http://t.qkme.me/3oi5rs.jpg。我必须使用UITextView因为需要多行支持,我尝试了所有方法并得出结论,我必须使用CoreText。几乎所有的方案都已实现,但在文本视图包裹的点上卡住了。我的UITextView子视图中的drawRect例程正确绘制描边文本,直到文字换行。即使用户输入的文本被换行符包裹,我绘制的描边文本也没有换行。这是我的drawRect方法实现:https://gist.github.com/4498988。在第29行,我使用字符包装:
CTLineBreakMode linebreakmode = kCTLineBreakByCharWrapping;

我已经尝试了自动换行选项(也是默认选项),但没有用。

我的问题是: 如何使我所绘制的文本正确换行,以便其作为输入文本的轮廓呈现?


出了什么问题?你有什么问题? - user1118321
我也不理解这个问题。你觉得在文本上加一些阴影怎么样? - Tommy Devoy
抱歉,已更新原问题以使其更清晰。 - trunal bhanse
@ttarules,我需要为每个输入的字符添加轮廓,而不是整个文本。感谢您的建议! - trunal bhanse
3个回答

2
// make your UITextView as a subclass of UITextView
// and override -drawRect: method in your UITextView subclass 
- (void)drawRect:(CGRect)rect
{
    self.textColor = [UIColor clearColor];

    [self setTypingAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, _textBaseColor, NSForegroundColorAttributeName, nil ]]; // _textBaseColor is any color of your choice
    CGRect newRect = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetTextDrawingMode(context, kCGTextStroke);
    // Make the thickness of the outline shadow. and increase the y position of shadow rect by 2.
    CGContextSetLineWidth(context, (TEXTOUTLINE_PERCENT/100 * self.font.pointSize)+1); // TEXTOUTLINE_PERCENT can be 25.
    CGContextSetLineJoin(context, kCGLineJoinRound);
    CGContextSetLineCap(context, kCGLineCapButt);
    CGContextSetStrokeColorWithColor(context, [UIColor clearColor].CGColor);
    CGRect shadowrect = newRect;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        shadowrect.origin.y += 0.5;
    }
    else
    {
        shadowrect.origin.y += 2;
    }

    [self.text drawInRect:shadowrect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, SHADOW_COLOR , NSForegroundColorAttributeName, nil]]; // SHADOW_COLOR can be [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.3]

    // Make the thickness of the outline border of the text.
    CGContextSetLineWidth(context, TEXTOUTLINE_PERCENT/100 * self.font.pointSize); // TEXTOUTLINE_PERCENT can be 25.
    CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
    [self.text drawInRect:newRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, self.textOutlineColor , NSForegroundColorAttributeName,  nil]];

    // Draw filled text. This is the actual text.
    CGContextSetTextDrawingMode(context, kCGTextFill);
    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
    [self.text drawInRect:newRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, _textBaseColor, NSForegroundColorAttributeName,_textBaseColor, NSStrokeColorAttributeName, nil]];
    [super drawRect:rect];
}

能否请您[编辑]您的答案,解释一下为什么这段代码可以回答问题?仅有代码的答案是不被鼓励的,因为它们无法教授解决方案。 - DavidPostill

0

只需要使用CSS创建一个字符串

NSString *htmlstring = [[NSString alloc] initWithFormat:@"<html><font style=\"text-shadow: 0 0 0.2em #F87, 0 0 0.2em #F87\">%@</font></html>", YourTextView.text, nil];

这将使TextView中的任何文本在网页上发光。如果您愿意,还可以给它一个黑色背景...使用此代码:

NSString *htmlstring = [[NSString alloc] initWithFormat:@"<html><body bgcolor=\"#000000\"><font style=\"text-shadow: 0 0 0.2em #F87, 0 0 0.2em #F87\">%@</font></body></html>", YourTextView.text, nil];

现在将其保存为html文件并加载到UIWebView中。或者通过javascript将其注入到URL中,然后将该URL加载到UIWebView中。

将UIWebView的框架和位置设置为与UITextView相匹配,以便它可以覆盖在其上,并显示带有黑色背景的红色发光文本。


谢谢你的建议,Albert。但是我想要在用户输入时“实时”更新UITextView。看起来你的解决方案需要在用户完成编辑后再放置UIWebView? - trunal bhanse
你可以禁用UIWebView,这样用户就可以通过它进行点击并开始输入,它会自动更新(因为几乎没有加载时间,因为HTML文件存储在本地,所以您不需要WiFi或任何东西来检索它),您可以添加一个闪烁的蓝线来模拟UIWebView是UITextView,它看起来非常逼真,然后WebView可以实时更新。唯一的问题是尝试将光标移回文本的先前部分或尝试选择要复制/粘贴的文本...那是行不通的 /: - Albert Renshaw
如果你能够以某种方式使UITextView上的文本透明,那么你可以将文本视图放在顶部,然后用户仍然可以看到闪烁的蓝线表示光标当前位置,并且用户可以自由地编辑,就像它是一个真正的文本视图一样,即使他们看到的是一个UIWebView。 - Albert Renshaw
哦!!!或者只需使用HTML创建UITextView,他们就可以编辑网页了...您可以通过JavaScript传递变量!然后它将像编辑UITextView一样,但他们将在应用程序中的虚假网站上编辑TextArea,该网站具有红色发光文本! - Albert Renshaw
当然,这是我三个方案中最好的解决方案。祝你好运!上帝保佑! - Albert Renshaw
添加了一个新的答案,它可以工作!测试一下吧 :) 它在这个答案上面。祝好运! - Albert Renshaw

0
创建一个HTML文件,其中包含可编辑的文本字段(TextArea),并且文字会呈现红色发光效果。
设置所有元素的背景为透明。
将其转换为字符串,并加载到位于所需放置文字的图像上方的UIWebView中。
将HTML字符串加载到UIWebView中,并且使UIWebView本身也透明。
*还需要将您的UIWebView定义为属性并进行合成。
以下是代码(不包括合成和属性部分)。
.h:
@interface ViewController : UIViewController <uiwebviewdelegate></uiwebviewdelegate> {
    IBOutlet UIWebView *webView;
    //... other objects you already have can go here too..
}

.m:

self.webView.delegate = self;
NSString *htmlstring = [[NSString alloc] initWithFormat:@"<html><body style='background-color: transparent;'><textarea name='myTextArea'cols='20' rows='10' style='text-shadow: 0 0 0.2em #F87, 0 0 0.2em #F87; background-color:transparent; border:none'>You Can Edit This Text.</textarea></body></html>"];
[self.webView loadHTMLString:htmlstring baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
self.webView.opaque = NO;
self.webView.backgroundColor = [UIColor clearColor];

编辑:这是“webView”属性和合成代码

@property(nonatomic,retain)IBOutlet UIWebView *nubrowser; //put in .h file at end of "@Interface" function after the closing curly bracket ("}")

@synthesize webView; //put in .m file directly after "@implementation" function

更改htmlstring中innerHTML的字体大小、发光颜色以及其他所有内容。如果您计划与其他内容一起使用UIWebView,请不要忘记合成它并将其设置为属性。 - Albert Renshaw
请注意,如果您想让HTML TextArea像UITextView一样滚动,您需要添加一个CSS属性。我现在记不清它是什么了,但在谷歌上很容易找到...就像overflow:touch-scroll或类似的东西。 - Albert Renshaw
你不需要这个,这只是为了将来想要使用此方法来放置文本以外的其他内容的人而准备的。 - Albert Renshaw
注意2:要从HTML的TextArea中检索文本,请通过JavaScript传递“innerHTML.myTextArea”变量(如果您不确定如何执行此操作,可以轻松地在Google上搜索)。 - Albert Renshaw
注意事项3:如果您在视图控制器.h文件中定义了webView,那么您可能不需要使用“self.webView”,只需使用“webView”即可。 - Albert Renshaw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接