मैं एक UIButton में पाठ के दाईं ओर छवि कैसे डालूं?


300

अगर मैं इससे बच सकता हूं तो मैं एक सबव्यू का उपयोग नहीं करना चाहता। मैं UIButtonएक पृष्ठभूमि छवि, पाठ और उसमें एक छवि चाहता हूं । अभी, जब मैं ऐसा करता हूं, तो छवि पाठ के बाईं ओर होती है। पृष्ठभूमि छवि, पाठ और छवि सभी में अलग-अलग हाइलाइट अवस्थाएं हैं।


यहां बढ़ती सूची में एक और "हैक" जोड़ने के लिए: आप अपने बटन शीर्षक + एक स्थान + छवि (एक NSTextAttachment के रूप में) युक्त एक जिम्मेदार स्ट्रिंग के लिए बटन का एट्रिब्यूटटाइल सेट कर सकते हैं। जैसा कि आप चाहते हैं कि इसे संरेखित करने के लिए आपको अनुलग्नक की सीमा को मोड़ना होगा (देखें stackoverflow.com/questions/26105803/… )।
मानव

जवाबों:


266

सुझाए गए कुछ जवाबों के बहुत रचनात्मक और बेहद चालाक होने के बावजूद, सबसे सरल समाधान इस प्रकार है:

button.semanticContentAttribute = UIApplication.shared
    .userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft

कि जैसे ही आसान। एक बोनस के रूप में, छवि दाएं से बाएं स्थानों में बाईं ओर होगी।

EDIT : जैसा कि सवाल कुछ ही बार पूछा गया है, यह iOS 9 + है


88
मुझे विश्वास नहीं होता कि यह उत्तर स्वीकार किया गया था। कोई भी अपने अनुप्रयोगों के लिए स्थानीयकरण नहीं करता है?
ज़ोल्टन

6
@pallzoltan: यह सवाल का जवाब देता है (यानी। "मैं UIButton में पाठ के दाईं ओर छवि कैसे डालूं?")। इससे स्थानीयकरण को क्या मिला है?
बेंजामिन

16
जब आप अपने लेआउट को RTL भाषाओं में "फ़्लिप" नहीं करना चाहते हैं तो कई स्थितियाँ नहीं हैं। सीधे सेटिंग semanticContentAttributeकेवल हैक / वर्कअराउंड है, वास्तविक समाधान नहीं।
ज़ोल्टन

6
मेरा दृष्टिकोण यह है कि आप नहीं जानते कि प्रश्न पूछने वाला व्यक्ति क्या निर्माण कर रहा है, इसलिए यह लेआउट के लिए लचीलेपन के साथ हमेशा बेहतर होता है।
ज़ोल्टन

2
@ ज़ोल्टन स्थानीयकरण एक समस्या नहीं है, बस वर्तमान लोकेल के आधार पर संपत्ति को उल्टा करें।
मानवमल

560

सबसे सरल समाधान:

iOS 10 और ऊपर, स्विफ्ट:

button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

IOS 10 से पहले, Swift / Obj-C:

button.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.titleLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

8
मैंने इसका उपयोग नेविगेशन बार शीर्षक दृश्य के लिए किया था और एक गड़बड़ थी। यह पहली बार लोड होने पर ठीक है, लेकिन जब आप किसी व्यू कंट्रोलर को धक्का देते हैं और उसे पॉप करते हैं, तो शीर्षक फ़्लिप हो जाता है।
फंक्शनल 7

@WoominJoshPark दिलचस्प ... मैं केवल यह अनुमान लगा सकता हूं कि यह इसलिए है क्योंकि परिवर्तन आंतरिक रूप से नेविगेशनल पॉप एनिमेशन के लिए एनिमेटेड है।
लियाओ जियान जी

1
मैं अगर यह क्रम में autolayout बाधा संघर्ष के बारे में शिकायतों खड़ी कर रहा है यह () layoutSubviews में इस जोड़कर निर्धारित किया जा सकता पाया
Vlad

1
मैं पाठ और छवि के बीच अधिक स्थान कैसे रख सकता हूं?
रोहिनब

2
@rohinb @ jose920405 पैडिंग के लिए ImageEdgeInsets और ContentEdgeInsets सेट करने का प्रयास करें (ध्यान रखें कि वे उलट गए हैं)। उदाहरण के लिए button.ImageEdgeInsets = new UIEdgeInsets(0, -leftPadding, 0, leftPadding); button.ContentEdgeInsets = new UIEdgeInsets(0, 0, 0, leftPadding);। यह ज़मारिन में है, लेकिन स्विफ्ट / ओबज-सी में आसानी से पर्याप्त अनुवाद करना चाहिए।
ली रिचर्डसन

267

XCODE 9 (वाया इंटरफ़ेस बिल्डर) के लिए अद्यतन

इंटरफ़ेस बिल्डर से एक आसान तरीका है

UIButton का चयन करें और उपयोगिताएँ> अर्थ : देखें में इस विकल्प का चयन करें

बाएं से दाएं यहां छवि विवरण दर्ज करें बस! अच्छा और सरल!

वैकल्पिक - दूसरा चरण:

यदि आप छवि और शीर्षक के बीच रिक्ति को समायोजित करना चाहते हैं, तो आप यहाँ इमेज इनसेट को बदल सकते हैं :

यहां छवि विवरण दर्ज करें

उम्मीद है की वो मदद करदे!


2
Xcode 9.0 बीटा 5 (9M202q) में, आप दुर्भाग्य से केवल रनटाइम पर परिणाम देखते हैं- स्टोरीबोर्ड में यह अभी भी बाईं ओर की छवि दिखाता है। यह भी ध्यान दें कि इसकी वजह से सही इनसेट सेट करने के लिए कुछ परीक्षण और त्रुटि होती है।
पीडीके

3
कृपया इसे इस तरह से न करें - यह दाईं-बाईं भाषाओं के लिए स्थानीयकरण को तोड़ता है।
20

169

UIButton को उपवर्ग पूरी तरह से अनावश्यक है। इसके बजाय आप बस इमेज इनसेट के लिए एक हाई लेफ्ट इनसेट वैल्यू और टाइटल के लिए एक छोटा राइट इनसेट सेट कर सकते हैं। कुछ इस तरह:

button.imageEdgeInsets = UIEdgeInsetsMake(0., button.frame.size.width - (image.size.width + 15.), 0., 0.);
button.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., image.size.width);

3
यह काम किया है, लेकिन बस याद रखें कि आज ऑटोलैयूट के साथ आपको इसे व्यूडायडियर पर करना होगा, न कि व्यूडीडलड पर
होला सोया एडु फेलिज नवाडीद

91

मैं Inspire48 को इस बात का श्रेय दे रहा हूं । उनके सुझाव के आधार पर और उस अन्य प्रश्न को देखते हुए मैं इस पर आया। उपक्लास यूबूटन और इन तरीकों को ओवरराइड करता है।

@implementation UIButtonSubclass

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super imageRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) -  self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMinX(frame) - CGRectGetWidth([self imageRectForContentRect:contentRect]);
    return frame;
}

@end

3
UIButton एक वर्ग क्लस्टर है और इसे उपवर्गित नहीं किया जाना चाहिए।
स्कॉट बेरेवेट्स

50
यह सच नहीं है, प्रलेखन स्पष्ट रूप से उपवर्ग का उल्लेख करता है और उन तरीकों को प्रदान करता है जिन्हें आपको कस्टम लेआउट व्यवहार के लिए ओवरराइड करना चाहिए।
टार्क

2
developer.apple.com/library/ios/documentation/uikit/reference/… buttonWithType If you subclass UIButton, this method does not return an instance of your subclass. If you want to create an instance of a specific subclass, you must alloc/init the button directly और backgroundRectForBoundsकस्टम पृष्ठभूमि श्रंगार प्रदान करने वाले उपवर्ग इस विधि को ओवरराइड कर सकते हैं और किसी भी कस्टम सामग्री पर बटन को खींचने से रोकने के लिए एक संशोधित सीमा आयत लौटा सकते हैं। विधियाँ, लेकिन मुझे लगता है कि वे उपवर्गों को बुरा नहीं मानते।
क्रिस्टोफरकॉटन

1
ऐसा लगता है कि छवि फ़्रेम मिरर करने के लिए यह फ़ॉर्मूला बेहतर है: frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) - self.imageEdgeInsets.right + self.imageEdgeInsets.left - frame.origin.x;यह UIControlContentHorizontalAlignmentCenterदूसरों के लिए बेहतर काम करता है ...
k06a

@ GwendalRoué क्योंकि यह छोटा है इसका मतलब यह नहीं है कि यह बेहतर है। यह एक हैकियर तरीका है, और यह बटन को वास्तविक इनसेट्स को अनदेखा करता है, और दाएं-बाएं भाषाओं में टूट सकता है। इस उत्तर के साथ आपके पास लेआउट का पूर्ण नियंत्रण है
Accatyyc

76

शीर्षक बदलने पर बस इनसेट को अपडेट करें। आपको दूसरी तरफ एक समान और विपरीत इनसेट के साथ इनसेट के लिए क्षतिपूर्ति करने की आवश्यकता है।

[thebutton setTitle:title forState:UIControlStateNormal];
thebutton.titleEdgeInsets = UIEdgeInsetsMake(0, -thebutton.imageView.frame.size.width, 0, thebutton.imageView.frame.size.width);
thebutton.imageEdgeInsets = UIEdgeInsetsMake(0, thebutton.titleLabel.frame.size.width, 0, -thebutton.titleLabel.frame.size.width);

3
आप [thebutton.titleLabel sizeToFit];पहले जोड़ना चाह सकते हैं । यदि आपने किसी लेआउट को ट्रिगर नहीं किया है तो चौड़ाई शून्य हो सकती है। वही छवि के आकार के लिए जाता है (चित्र के आकार के बजाय केवल UIImage.size का उपयोग करें)
19

@delrox अच्छी बात है। उपयोग कर सकते हैं titleWidth = [self.titleLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.bounds.size.height)].width;(या यदि आप अभी तक स्थापित नहीं किए जा रहे बटन फ्रेम के बारे में चिंतित हैं, तो ऊँचाई के लिए CGFLOAT_MAX का उपयोग करें) औरimageWidth = self.currentImage.size.width;
डेव गोल्डमैन


मुझे इसे layoutSubviewsअपने UITableViewCellउपवर्ग में रखना था लेकिन इसका अच्छा काम करना था। धन्यवाद!
रायनग

60

जनवरी 2016 तक ये सभी उत्तर अनावश्यक हैं। इंटरफ़ेस बिल्डर में, व्यू सेमैटिक को सेट करें Force Right-to-Left, या यदि आप प्रोग्रामेटिक तरीका पसंद करते हैं, तो semanticContentAttribute = .forceRightToLeftइससे आपके टेक्स्ट के दाईं ओर छवि दिखाई देगी।


5
अफसोस की बात है कि यह 9 से बड़े ios का समर्थन नहीं करता है। फिर भी अच्छा जवाब है, थियो।
एडी

1
मुझे यह बताते हुए दुःख हो रहा है कि इसे UIButButtonItem के लिए उपयोग करने वाले UIButton पर सेट करने से कोई परिवर्तन नहीं हुआ।
अमेलिया

जैसा कि @Amelia ने उल्लेख किया है, यदि आप कॉल करते हैं तो यह काम नहीं करता है UIBarButtonItem(customView: button), लेकिन अगर आप कुछ खाली दृश्य के अंदर बटन लपेटते हैं तो यह काम करेगा
tt.Kilew

@ tt.Kilew, XCode 8.1 के उपयोग से आपको यह काम मिलता है। मैंने uiButton.semanticContentAttribute = .RRTTLLeft सेट किया और नेक्स्ट बटन प्रदान किया = UIBarButtonItem (customView: uiButton)
Biryukov

53

इंटरफ़ेस बिल्डर में, आप UIButton के लिए एज इनसेट्स को कॉन्फ़िगर कर सकते हैं, अलग-अलग तीन भागों में से प्रत्येक: सामग्री, छवि, शीर्षक

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

Xcode 8:

यहां छवि विवरण दर्ज करें


3
वास्तव में मेरे विचार इस में सर्वश्रेष्ठ उत्तर stackoverflow.com/a/39013315/1470374 ))
गेनेडी Ryabkin

25

अपडेट: स्विफ्ट 3

class ButtonIconRight: UIButton {
    override func imageRect(forContentRect contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRect(forContentRect: contentRect)
        imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
    }

    override func titleRect(forContentRect contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRect(forContentRect: contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
        }
        return titleFrame
    }
}

स्विफ्ट 2 का मूल उत्तर:

एक समाधान जो स्विफ्ट कार्यान्वयन उदाहरण के साथ सभी क्षैतिज संरेखण को संभालता है। यदि आवश्यक हो तो बस उद्देश्य-सी में अनुवाद करें।

class ButtonIconRight: UIButton {
    override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRectForContentRect(contentRect)
        imageFrame.origin.x = CGRectGetMaxX(super.titleRectForContentRect(contentRect)) - CGRectGetWidth(imageFrame)
        return imageFrame
    }

    override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRectForContentRect(contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
        }
        return titleFrame
    }
}

यह भी ध्यान देने योग्य है कि यह काफी अच्छी छवि और शीर्षक इनसेट को संभालता है।

Jasongregori उत्तर से प्रेरित;)


1
इस समाधान ने मेरे लिए काम किया, हालांकि मेरी छवि को इसके चारों ओर कुछ स्थान की आवश्यकता थी इसलिए मैंने निम्नलिखित कोड जोड़ा: self.contentEdgeInsets = UIEdgeInsetsMake (10.0, 10.0, 10.0, 10.0)
user1354603

1
मुझे यह तरीका पसंद है क्योंकि आप @IBDesignableकक्षा में जोड़ सकते हैं और देख सकते हैं कि यह डिज़ाइन समय पर फ़्लिप हो गया है।
जेम्स टॉमी

मैं इस समाधान को पसंद करता हूं क्योंकि यह तब भी काम करता है जब नेविगेशन बार में रखा जाता है।
एल भयानक

10

यदि यह UIBarButtonItem में किए जाने की आवश्यकता है , तो देखने में अतिरिक्त रैपिंग का उपयोग किया जाना चाहिए
यह काम करेगा

let view = UIView()
let button = UIButton()
button.setTitle("Skip", for: .normal)
button.setImage(#imageLiteral(resourceName:"forward_button"), for: .normal)
button.semanticContentAttribute = .forceRightToLeft
button.sizeToFit()
view.addSubview(button)
view.frame = button.bounds
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: view)

यह काम नहीं करेगा

let button = UIButton()
button.setTitle("Skip", for: .normal)
button.setImage(#imageLiteral(resourceName:"forward_button"), for: .normal)
button.semanticContentAttribute = .forceRightToLeft
button.sizeToFit()
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

7

यहां UIButtonकेंद्र संरेखित सामग्री के साथ समाधान है। इस कोड को मेकअप छवि सही गठबंधन और उपयोग करने की अनुमति देता imageEdgeInsetsहै और titleEdgeInsetsकीमती स्थिति के लिए।

यहां छवि विवरण दर्ज करें

UIButtonअपने कस्टम वर्ग के साथ उपवर्ग जोड़ें और जोड़ें:

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    CGRect frame = [super imageRectForContentRect:contentRect];
    CGFloat imageWidth = frame.size.width;
    CGRect titleRect = CGRectZero;
    titleRect.size = [[self titleForState:self.state] sizeWithAttributes:@{NSFontAttributeName: self.titleLabel.font}];
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect {
    CGFloat imageWidth = [self imageForState:self.state].size.width;
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    return frame;
}

1
इसके अलावा आप स्टोरीबोर्डेड yadi.sk/i/fd6Si-BJqzCFD
निकोले शुबेनकोव

6

यह होने के नाते कि रूपांतरण समाधान iOS 11 में काम नहीं करता है मैंने एक नया दृष्टिकोण लिखने का फैसला किया है।

बटन को समायोजित करना semanticContentAttribute है को को करने से दाईं ओर इमेज अच्छी तरह से दिखाई देती है। इस वजह से यह आदर्श समाधान है। हालाँकि मुझे अभी भी RTL समर्थन की आवश्यकता है। तथ्य यह है कि एक app एक ही सत्र में लेआउट दिशा नहीं बदल सकते हैं इस मुद्दे को आसानी से हल करता है।

उस के साथ कहा, यह बहुत सीधे आगे है।

extension UIButton {
    func alignImageRight() {
        if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
            semanticContentAttribute = .forceRightToLeft
        }
        else {
            semanticContentAttribute = .forceLeftToRight
        }
    }
}

6

एक्सटेंशन का रास्ता

कस्टम ऑफसेट के साथ दाईं ओर छवि सेट करने के लिए एक्सटेंशन का उपयोग करना

   extension UIButton {
    func addRightImage(image: UIImage, offset: CGFloat) {
        self.setImage(image, for: .normal)
        self.imageView?.translatesAutoresizingMaskIntoConstraints = false
        self.imageView?.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true
        self.imageView?.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -offset).isActive = true
    }
}

4

स्विफ्ट-UiButton को आगे बढ़ाएं और इन लाइनों को डालें

    if let imageWidth = self.imageView?.frame.width {
        self.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth);
    }

    if let titleWidth = self.titleLabel?.frame.width {
        let spacing = titleWidth + 20
        self.imageEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, -spacing);
    }

3

पिओट्र टॉमसिक के सुरुचिपूर्ण समाधान पर निर्माण: यदि आप बटन लेबल और छवि के बीच थोड़ा सा अंतर रखना चाहते हैं , तो इसे अपने एज इनसेट्स में इस प्रकार शामिल करें (मेरे कोड को यहां कॉपी करना जो मेरे लिए पूरी तरह से काम करता है):

    CGFloat spacing          = 3;
    CGFloat insetAmount      = 0.5 * spacing;

    // First set overall size of the button:
    button.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
    [button sizeToFit];

    // Then adjust title and image insets so image is flipped to the right and there is spacing between title and image:
    button.titleEdgeInsets   = UIEdgeInsetsMake(0, -button.imageView.frame.size.width - insetAmount, 0,  button.imageView.frame.size.width  + insetAmount);
    button.imageEdgeInsets   = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width + insetAmount, 0, -button.titleLabel.frame.size.width - insetAmount);

आपके समाधान के लिए धन्यवाद Piotr!

एरिक


@ लूलियन: मैं हाल ही में (यहां स्वीकृत जवाब) के बजाय लियाओ जियान जी के समाधान का उपयोग कर रहा हूं, और यह शानदार ढंग से काम करता है और एक बहुत ही सुंदर समाधान है।
एरिक वैन डेर नीट

यह मेरे लिए काम नहीं करता है क्योंकि यह पाठ के संरेखण को बदलता है।
इयूलियन ओनोफ्रेई

3

अपने आप करो। Xcode10, स्विफ्ट 4,

प्रोग्राम यूआई डिजाइन के लिए

यहां छवि विवरण दर्ज करें

 lazy var buttonFilter : ButtonRightImageLeftTitle = {
    var button = ButtonRightImageLeftTitle()
    button.setTitle("Playfir", for: UIControl.State.normal)
    button.setImage(UIImage(named: "filter"), for: UIControl.State.normal)
    button.backgroundColor = UIColor.red
    button.contentHorizontalAlignment = .left
    button.titleLabel?.font = UIFont.systemFont(ofSize: 16)
    return button
}()

एज इंसेट वैल्यू उस आयत द्वारा दर्शाए गए क्षेत्र को सिकोड़ने या विस्तारित करने के लिए एक आयत पर लागू होती है। आमतौर पर, एज इनसेट का उपयोग व्यू लेआउट को देखने के फ्रेम को संशोधित करने के लिए किया जाता है। सकारात्मक मान निर्दिष्ट राशि से फ्रेम को इनसेट (या सिकुड़) करते हैं। नकारात्मक मानों के कारण फ्रेम निर्दिष्ट राशि से शुरू (या विस्तारित) होता है।

class ButtonRightImageLeftTitle: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        guard imageView != nil else { return }

        imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: -((imageView?.bounds.width)! + 10), bottom: 0, right: 0 )

    }
}

StoryBoard UI डिज़ाइन के लिए

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें


क्या यह अधिक सुरुचिपूर्ण करने का एक तरीका है?
ज़ापोरोज़ेन्को ओलेकेंडर


2

@ Piotr के उत्तर को लिया और इसे एक स्विफ्ट एक्सटेंशन में बनाया। इसे कॉल करने से पहले छवि और शीर्षक सेट करना सुनिश्चित करें, ताकि बटन ठीक से आकार ले सके।

extension UIButton {

/// Makes the ``imageView`` appear just to the right of the ``titleLabel``.
func alignImageRight() {
    if let titleLabel = self.titleLabel, imageView = self.imageView {
        // Force the label and image to resize.
        titleLabel.sizeToFit()
        imageView.sizeToFit()
        imageView.contentMode = .ScaleAspectFit

        // Set the insets so that the title appears to the left and the image appears to the right. 
        // Make the image appear slightly off the top/bottom edges of the button.
        self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -1 * imageView.frame.size.width,
            bottom: 0, right: imageView.frame.size.width)
        self.imageEdgeInsets = UIEdgeInsets(top: 4, left: titleLabel.frame.size.width,
            bottom: 4, right: -1 * titleLabel.frame.size.width)
    }
}

}


2

एक तेज़ विकल्प जो किसी भी इनसेट के साथ खेलने के बिना आपको क्या करना है:

class RightImageButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let  textSize = titleLabel?.intrinsicContentSize(),
                imageSize = imageView?.intrinsicContentSize() {
            let wholeWidth = textSize.width + K.textImageGap + imageSize.width
            titleLabel?.frame = CGRect(
                x: round(bounds.width/2 - wholeWidth/2),
                y: 0,
                width: ceil(textSize.width),
                height: bounds.height)
            imageView?.frame = CGRect(
                x: round(bounds.width/2 + wholeWidth/2 - imageSize.width),
                y: RoundRetina(bounds.height/2 - imageSize.height/2),
                width: imageSize.width,
                height: imageSize.height)
        }
    }

    struct K {
        static let textImageGap: CGFloat = 5
    }

}

1

एक बार मैंने ऑटो लेआउट को सक्षम करते हुए यहां बताए गए समाधानों को काम करना बंद कर दिया । मुझे अपने साथ आना पड़ा:

उपवर्ग UIButton और ओवरराइड layoutSubviewsविधि:

//
//  MIThemeButtonImageAtRight.m
//  Created by Lukasz Margielewski on 7/9/13.
//

#import "MIThemeButtonImageAtRight.h"

static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets);

@implementation MIThemeButtonImageAtRight

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGRect contentFrame = CGRectByApplyingUIEdgeInsets(self.bounds, self.contentEdgeInsets);

    CGRect frameIcon = self.imageView.frame;
    CGRect frameText = self.titleLabel.frame;

    frameText.origin.x = CGRectGetMinX(contentFrame) + self.titleEdgeInsets.left;
    frameIcon.origin.x = CGRectGetMaxX(contentFrame) - CGRectGetWidth(frameIcon);

    self.imageView.frame = frameIcon;
    self.titleLabel.frame = frameText;
}

@end

static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets){

    CGRect f = frame;

    f.origin.x += insets.left;
    f.size.width -= (insets.left + insets.right);
    f.origin.y += (insets.top);
    f.size.height -= (insets.top + insets.bottom);

    return f;

}

परिणाम:

यहां छवि विवरण दर्ज करें


1

jasongregori द्वारा दिया गया स्विफ्ट 3.0 माइग्रेशन समाधान

class ButtonIconRight: UIButton {
        override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
            var imageFrame = super.imageRect(forContentRect: contentRect)
           imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
        }

        override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
            var titleFrame = super.titleRect(forContentRect: contentRect)
            if (self.currentImage != nil) {
                titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
            }
            return titleFrame
        }

1

मैंने मानक बटन छवि दृश्य का उपयोग नहीं करने का फैसला किया क्योंकि प्रस्तावित समाधान इसे चारों ओर स्थानांतरित करने के लिए महसूस किया गया। यह मुझे वांछित सौंदर्य मिला है, और बाधाओं को बदलकर बटन को फिर से बदलना सहज है:

extension UIButton {
    func addRightIcon(image: UIImage) {
        let imageView = UIImageView(image: image)
        imageView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(imageView)

        let length = CGFloat(15)
        titleEdgeInsets.right += length

        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: self.titleLabel!.trailingAnchor, constant: 10),
            imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
            imageView.widthAnchor.constraint(equalToConstant: length),
            imageView.heightAnchor.constraint(equalToConstant: length)
        ])
    }
}

सही तीर के साथ बटन


यह नल की प्रतिक्रिया नहीं देता है, पाठ मर जाता है लेकिन छवि नहीं करता है
टेडी के

0

स्विफ्ट 3:

open override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
    var frame = super.imageRect(forContentRect: contentRect)
    let  imageWidth = frame.size.width
    var titleRect = CGRect.zero
    titleRect.size = self.title(for: self.state)!.size(attributes: [NSFontAttributeName: self.titleLabel!.font])
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame
}

open override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
    var frame = super.titleRect(forContentRect: contentRect)
    if let imageWidth = self.image(for: self.state)?.size.width {
        frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    }
    return frame
}

0

बाधाओं के बारे में कैसे? सिमेंटिक कॉन्टेंट एट्रिब्यूट के विपरीत, वे शब्दार्थ नहीं बदलते हैं। कुछ इस तरह शायद:

 button.rightAnchorconstraint(equalTo: button.rightAnchor).isActive = true

या उद्देश्य-सी में:

[button.imageView.rightAnchor constraintEqualToAnchor:button.rightAnchor].isActive = YES;

कैविट्स: अनटाइटेड, iOS 9+


0

UIButton के भीतर सही संरेखित छवि के लिए कोड के नीचे प्रयास करें

btn.contentHorizontalAlignment = .right

यह वह नहीं है जिसके बारे में लेखक ने पूछा है।
मत्युज

0

इंटरनेट के आसपास से कई समाधानों की कोशिश करने के बाद, मैं सटीक आवश्यकता प्राप्त नहीं कर रहा था। इसलिए मैंने कस्टम उपयोगिता कोड लिखना समाप्त कर दिया। भविष्य में किसी की मदद करने के लिए पोस्ट करना। स्विफ्ट 4.2 पर परीक्षण किया गया

// This function should be called in/after viewDidAppear to let view render
    func addArrowImageToButton(button: UIButton, arrowImage:UIImage = #imageLiteral(resourceName: "my_image_name") ) {
        let btnSize:CGFloat = 32
        let imageView = UIImageView(image: arrowImage)
        let btnFrame = button.frame
        imageView.frame = CGRect(x: btnFrame.width-btnSize-8, y: btnFrame.height/2 - btnSize/2, width: btnSize, height: btnSize)
        button.addSubview(imageView)
        //Imageview on Top of View
        button.bringSubviewToFront(imageView)
    }

0

इस समस्या के लिए आप "UIImage view के साथ लेबल" के अंदर UIView बना सकते हैं और UIView वर्ग को UIControl के रूप में सेट कर सकते हैं और IBAction को साइड में tuch बना सकते हैं

यहां छवि विवरण दर्ज करें


0

स्विफ्ट 4 और 5

UIButton छवि (RTL और LTR) की दिशा बदलें

extension UIButton {
    func changeDirection(){
       isArabic ? (self.contentHorizontalAlignment = .right) : (self.contentHorizontalAlignment = .left)
        // left-right margin 
        self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
        self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    }
}

क्या है Utility?
बायरन कोएट्सी

मैं सिर्फ उपयोगिता को हटाता हूं, यह मेरे कोड में एक वर्ग है जहां मैं यह जांच सकता हूं कि चयनित भाषा अरबी है या अंग्रेजी
रशीद लतीफ

0

Xcode 11.4 स्विफ्ट 5.2

इस तरह से शेवरॉन के साथ बैक बटन स्टाइल को मिरर करने की कोशिश करने वाले किसी के लिए:

यहां छवि विवरण दर्ज करें

import UIKit

class NextBarButton: UIBarButtonItem {

    convenience init(target: Any, selector: Selector) {

        // Create UIButton
        let button = UIButton(frame: .zero)

        // Set Title
        button.setTitle("Next", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17)

        // Configure Symbol
        let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
        let image = UIImage(systemName: "chevron.right", withConfiguration: config)
        button.setImage(image, for: .normal)

        // Add Target
        button.addTarget(target, action: selector, for: .touchUpInside)

        // Put the Image on the right hand side of the button
        // Credit to liau-jian-jie for this part
        button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

        // Customise spacing to match system Back button
        button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)

        self.init(customView: button)
    }
}

कार्यान्वयन:

override func viewDidLoad() {
    super.viewDidLoad()
    let nextButton = NextBarButton(target: self, selector: #selector(nextTapped))
    navigationItem.rightBarButtonItem = nextButton
}

@objc func nextTapped() {
    // your code
}

0

मैंने एक कस्टम बटन बनाया, जो इंस्पेक्टर से छवि स्थापित करने की अनुमति देता है। नीचे मेरा कोड है:

import UIKit

@IBDesignable
class CustomButton: UIButton {

    @IBInspectable var leftImage: UIImage? = nil
    @IBInspectable var gapPadding: CGFloat = 0

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }

    func setup() {

        if(leftImage != nil) {
            let imageView = UIImageView(image: leftImage)
            imageView.translatesAutoresizingMaskIntoConstraints = false

            addSubview(imageView)

            let length = CGFloat(16)
            titleEdgeInsets.left += length

            NSLayoutConstraint.activate([
                imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: gapPadding),
                imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
                imageView.widthAnchor.constraint(equalToConstant: length),
                imageView.heightAnchor.constraint(equalToConstant: length)
            ])
        }
    }
}

आप पाठ और छवि के बीच अंतर को समायोजित करने के लिए इंस्पेक्टर से गैप पैडिंग के मूल्य को समायोजित कर सकते हैं।

PS: @Mark Hennings उत्तर से कुछ कोड भाग का उपयोग किया

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.