একক লাইন UILabel এর পাশে NSTextAttachment চিত্রটি কেন্দ্র করুন


117

আমি একটি যুক্ত করতে চাই NSTextAttachment আমার বৈশিষ্ট্যযুক্ত স্ট্রিংয়ের সাথে চিত্র এবং এটি উল্লম্বভাবে কেন্দ্রে রাখতে চাই।

আমি আমার স্ট্রিং তৈরি করতে নিম্নলিখিত কোডটি ব্যবহার করেছি:

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:DDLocalizedString(@"title.upcomingHotspots") attributes:attrs];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [[UIImage imageNamed:@"help.png"] imageScaledToFitSize:CGSizeMake(14.f, 14.f)];
cell.textLabel.attributedText = [str copy];

তবে চিত্রটি সেলটির শীর্ষে প্রান্তিকিত হয় textLabel

পাঠ্য সংযুক্তি অফসেট সমস্যা স্ক্রিনশট

সংযুক্তিটি আঁকানো সেই রেক্টটকে আমি কীভাবে পরিবর্তন করতে পারি?


ইউআইআইমেজ এবং ভাইরাস বিপরীতে এনএসএসস্ট্রিং করার জন্য আমার একটি বিভাগ শ্রেণি রয়েছে। github.com/Praਦੀਪkn/TextWithImage উপভোগ করুন।
প্রদীপকেএন

উত্তর:


59

আপনি সাবক্লাসিং NSTextAttachmentএবং ওভাররাইড করে রেটটিকে পরিবর্তন করতে পারেন attachmentBoundsForTextContainer:proposedLineFragment:glyphPosition:characterIndex:। উদাহরণ:

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex {
    CGRect bounds;
    bounds.origin = CGPointMake(0, -5);
    bounds.size = self.image.size;
    return bounds;
}

এটি কোনও নিখুঁত সমাধান নয়। আপনাকে "চোখের দ্বারা" ওয়াই-উত্সটি বের করতে হবে এবং যদি আপনি ফন্ট বা আইকন আকার পরিবর্তন করেন তবে আপনি সম্ভবত Y- উত্সটি পরিবর্তন করতে চান। তবে আইকনটিকে পৃথক চিত্র দর্শনে না রেখে (যার নিজস্ব অসুবিধাগুলি রয়েছে) বাদ দিয়ে আমি এর থেকে ভাল আর কোনও উপায় খুঁজে পাচ্ছি না।


2
তারা কেন এটিকে ভোট দিয়েছিল তা জানেন না, এটি আমাকে এত বেশি সহায়তা করেছে
জ্যাস্পার

Y- উত্স হ'ল হরফ হস্তান্তরকারী। আমার উত্তর নীচে দেখুন।
ফটম্ন

4
ট্র্যাভিসের উত্তরটি সাবক্লাসিং ছাড়াই একটি ক্লিনার সমাধান।
সোলেপথিংটম

আরও তথ্যের জন্য, @ মিলিগ্রাম-হানের উত্তর স্ট্যাকওভারফ্লো.com / a / 45161058 / 280503 দেখুন (আমার মতে এটি প্রশ্নের নির্বাচিত উত্তর হওয়া উচিত))
বাগানফউইন

191

আপনি ফন্টের ক্যাপহাইট ব্যবহার করতে পারেন।

উদ্দেশ্য গ

NSTextAttachment *icon = [[NSTextAttachment alloc] init];
UIImage *iconImage = [UIImage imageNamed:@"icon.png"];
[icon setBounds:CGRectMake(0, roundf(titleFont.capHeight - iconImage.size.height)/2.f, iconImage.size.width, iconImage.size.height)];
[icon setImage:iconImage];
NSAttributedString *iconString = [NSAttributedString attributedStringWithAttachment:icon];
[titleText appendAttributedString:iconString];

দ্রুতগতি

let iconImage = UIImage(named: "icon.png")!
var icon = NSTextAttachment()
icon.bounds = CGRect(x: 0, y: (titleFont.capHeight - iconImage.size.height).rounded() / 2, width: iconImage.size.width, height: iconImage.size.height)
icon.image = iconImage
let iconString = NSAttributedString(attachment: icon)
titleText.append(iconString)

সংযুক্তি চিত্রটি পাঠ্যের বেসলাইনে রেন্ডার হয়। এবং এর y অক্ষটি মূল গ্রাফিক্স স্থানাঙ্ক সিস্টেমের মতো বিপরীত হয়। আপনি যদি চিত্রটিকে wardর্ধ্বমুখী করতে চান তবে ইতিবাচককে সেট করুন bounds.origin.y

চিত্রটি পাঠ্যের ক্যাপ হাইটের সাথে উল্লম্বভাবে কেন্দ্ররেখা করা উচিত। সুতরাং আমরা সেট করতে হবে bounds.origin.yকরতে (capHeight - imageHeight)/2

চিত্রটিতে কিছুটা ঠাণ্ডা প্রভাব এড়ানো, আমাদের y এর ভগ্নাংশের অংশটি গোল করা উচিত। তবে হরফ এবং ইমেজগুলি সাধারণত ছোট থাকে, এমনকি 1px পার্থক্য চিত্রটিকে ভুলরকমের মতো দেখায়। সুতরাং আমি বিভাজক আগে বৃত্তাকার ফাংশন প্রয়োগ। এটি y মানের ভগ্নাংশকে .0 বা .5 তে পরিণত করে

আপনার ক্ষেত্রে, চিত্রটির উচ্চতা হরফের হ্যাপির চেয়ে বড়। তবে আপনি একইভাবে ব্যবহার করতে পারেন। অফসেট ওয়াই মানটি নেতিবাচক হবে। এবং এটি বেসলাইনের নীচে থেকে বিছানো হবে।

এখানে চিত্র বর্ণনা লিখুন


ধন্যবাদ!!!!!!!!!!!!!!
অ্যালেক্স

107

ব্যবহার করে দেখুন - [NSTextAttachment bounds]। কোনও সাবক্লাসিংয়ের প্রয়োজন নেই।

প্রসঙ্গে, আমি UILabelসংযুক্তি চিত্র হিসাবে ব্যবহারের জন্য একটি রেন্ডার করছি , তারপরে যেমন সীমা নির্ধারণ করছি: attachment.bounds = CGRectMake(0, self.font.descender, attachment.image.size.width, attachment.image.size.height)এবং লেবেল চিত্রের মধ্যে পাঠ্যের বেসলাইনগুলি এবং পছন্দসই স্ট্রিং লাইনটিতে পাঠ্যকে আকাঙ্ক্ষিত হিসাবে।


এটি ততক্ষণ কাজ করে যতক্ষণ না আপনার ইমেজ স্কেল করার প্রয়োজন হয়।
ফটম্ন

12
সুইফট 3.0 এর জন্য:attachment.bounds = CGRect(x: 0.0, y: self.font.descender, width: attachment.image!.size.width, height: attachment.image!.size.height)
অ্যান্ডি

অান্তরিক ধন্যবাদ! descenderইউআইএফন্টের সম্পত্তি সম্পর্কে জানতেন না !
বেন

61

আমি এটির একটি নিখুঁত সমাধান পেয়েছি, যদিও এটি আমার নিজের জন্য একটি কবজির মতো কাজ করে, তবে আপনাকে নিজেরাই এটি চেষ্টা করে দেখতে হবে (সম্ভবত ধ্রুবকটি ডিভাইসের রেজোলিউশনের উপর নির্ভর করে এবং যা কিছু হতে পারে;)

func textAttachment(fontSize: CGFloat) -> NSTextAttachment {
    let font = UIFont.systemFontOfSize(fontSize) //set accordingly to your font, you might pass it in the function
    let textAttachment = NSTextAttachment()
    let image = //some image
    textAttachment.image = image
    let mid = font.descender + font.capHeight
    textAttachment.bounds = CGRectIntegral(CGRect(x: 0, y: font.descender - image.size.height / 2 + mid + 2, width: image.size.width, height: image.size.height))
    return textAttachment
}

কাজ করা উচিত এবং কোনওভাবেই অস্পষ্ট হওয়া উচিত নয় (ধন্যবাদ CGRectIntegral)


এটি পোস্ট করার জন্য ধন্যবাদ, এটি আমার বেশ ভাল পদ্ধতির দিকে নিয়ে যায়। আমি লক্ষ্য করেছি যে আপনি আপনার y স্থানাঙ্ক গণনায় কিছুটা জাদু যুক্ত করছেন।
বেন 21

2
আমি আমার ওয়াই-গণনার জন্য যা ব্যবহার করেছি তা এখানে: desce উত্সর্গকারী + (অ্যাবস (উতরক) + ক্যাপ হাইট) / 2 - আইকনহাইট / 2
বেন

Y উত্সের জন্য কেন +2?
উইলিয়াম লেগেট

@ উইলিয়ামলিগেট আমি সত্যিই জানি না, কেবল এটি চেষ্টা করে দেখেছি এবং এটি যে ফন্টের জন্য আমার পরীক্ষিত আকারগুলির জন্য কাজ করেছে (যেগুলি আমার প্রয়োজন ছিল) ..
বোরচেরো

ভাল অভিশাপ ... এই উত্তরটি আশ্চর্যজনক।
জিগিরোত্তো

38

কি সম্পর্কে:

CGFloat offsetY = -10.0;

NSTextAttachment *attachment = [NSTextAttachment new];
attachment.image = image;
attachment.bounds = CGRectMake(0.0, 
                               offsetY, 
                               attachment.image.size.width, 
                               attachment.image.size.height);

কোনও সাবক্লাসিংয়ের প্রয়োজন নেই


2
সেল্ফ.ফন্ট.ডেসেন্ডার ব্যবহার করার চেয়ে আরও ভাল কাজ করে (আইওএস 8 চলমান আইফোন 4 এস সিমুলেটারে যার ডিফল্ট মান 4 ডলার থাকে)। -10 ডিফল্ট ফন্ট শৈলী / আকারের জন্য আরও ভাল অনুমানের মতো দেখায়।
কেদার পরানজপে

10

@ ট্র্যাভিস সঠিক যে অফসেট হ'ল ফন্ট উতরক। আপনার যদি চিত্রটি স্কেল করতে হয় তবে আপনাকে এনএসটিেক্সটএটাকমেন্টের একটি সাবক্লাস ব্যবহার করতে হবে। নীচে কোডটি দেওয়া হয়েছে, যা এই নিবন্ধটি দ্বারা অনুপ্রাণিত হয়েছিল । আমি এটি একটি গিস্ট হিসাবে পোস্ট ।

import UIKit

class ImageAttachment: NSTextAttachment {
    var verticalOffset: CGFloat = 0.0

    // To vertically center the image, pass in the font descender as the vertical offset.
    // We cannot get this info from the text container since it is sometimes nil when `attachmentBoundsForTextContainer`
    // is called.

    convenience init(_ image: UIImage, verticalOffset: CGFloat = 0.0) {
        self.init()
        self.image = image
        self.verticalOffset = verticalOffset
    }

    override func attachmentBoundsForTextContainer(textContainer: NSTextContainer, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect {
        let height = lineFrag.size.height
        var scale: CGFloat = 1.0;
        let imageSize = image!.size

        if (height < imageSize.height) {
            scale = height / imageSize.height
        }

        return CGRect(x: 0, y: verticalOffset, width: imageSize.width * scale, height: imageSize.height * scale)
    }
}

নিম্নলিখিত হিসাবে ব্যবহার করুন:

var text = NSMutableAttributedString(string: "My Text")
let image = UIImage(named: "my-image")!
let imageAttachment = ImageAttachment(image, verticalOffset: myLabel.font.descender)
text.appendAttributedString(NSAttributedString(attachment: imageAttachment))
myLabel.attributedText = text

10

আপনার যদি খুব বড় আরোহণ হয় এবং আমার মতো চিত্রটি (ক্যাপের উচ্চতার মাঝখানে) রাখতে চান তবে এটি চেষ্টা করুন try

let attachment: NSTextAttachment = NSTextAttachment()
attachment.image = image
if let image = attachment.image{
    let y = -(font.ascender-font.capHeight/2-image.size.height/2)
    attachment.bounds = CGRect(x: 0, y: y, width: image.size.width, height: image.size.height).integral
}

Y গণনা নীচের চিত্র হিসাবে

এখানে চিত্র বর্ণনা লিখুন

নোট করুন যে y মান 0 হয় কারণ আমরা চিত্রটি উত্স থেকে নীচে নামাতে চাই

আপনি যদি এটিটি পুরো লেবেলের মাঝে থাকতে চান তবে এই y মানটি ব্যবহার করুন:

let y = -((font.ascender-font.descender)/2-image.size.height/2)

7

আমরা সুইফট 4-তে একটি এক্সটেনশন করতে পারি যা এর মতো কেন্দ্রিক চিত্রের সাথে একটি সংযুক্তি তৈরি করে:

extension NSTextAttachment {
    static func getCenteredImageAttachment(with imageName: String, and 
    font: UIFont?) -> NSTextAttachment? {
        let imageAttachment = NSTextAttachment()
    guard let image = UIImage(named: imageName),
        let font = font else { return nil }

    imageAttachment.bounds = CGRect(x: 0, y: (font.capHeight - image.size.height).rounded() / 2, width: image.size.width, height: image.size.height)
    imageAttachment.image = image
    return imageAttachment
    }
}

তারপরে আপনি কলটি চিত্র এবং ফন্টের নাম প্রেরণ করতে পারেন:

let imageAttachment = NSTextAttachment.getCenteredImageAttachment(with: imageName,
                                                                   and: youLabel?.font)

এবং তারপরে চিত্রটি সংযুক্ত করুন বৈশিষ্ট্যযুক্ত স্ট্রিংয়ের সাথে সংযুক্তি


1

আমার ক্ষেত্রে সাইজটিওফিট () কল করেছিল। দ্রুত 5.1

আপনার কাস্টম লেবেলের ভিতরে:

func updateUI(text: String?) {
    guard let text = text else {
        attributedText = nil
        return
    }

    let attributedString = NSMutableAttributedString(string:"")

    let textAttachment = NSTextAttachment ()
    textAttachment.image = image

    let sizeSide: CGFloat = 8
    let iconsSize = CGRect(x: CGFloat(0),
                           y: (font.capHeight - sizeSide) / 2,
                           width: sizeSide,
                           height: sizeSide)
    textAttachment.bounds = iconsSize

    attributedString.append(NSAttributedString(attachment: textAttachment))
    attributedString.append(NSMutableAttributedString(string: text))
    attributedText = attributedString

    sizeToFit()
}

0

সীমার উচ্চতার জন্য দয়া করে -lineFrag.size.height / 5.0 ব্যবহার করুন। এটি হুবহু চিত্রটি কেন্দ্র করে এবং সমস্ত ফন্টের আকারের জন্য পাঠ্যের সাথে একত্রিত হয়

override func attachmentBoundsForTextContainer(textContainer: NSTextContainer, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect
{
    var bounds:CGRect = CGRectZero

    bounds.size = self.image?.size as CGSize!
    bounds.origin = CGPointMake(0, -lineFrag.size.height/5.0);

    return bounds;
}

-lineFrag.size.height/5.0সঠিক নয়. পরিবর্তে এটি হরফ হস্তান্তরকারী হয়।
ফটম্ন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.