আইফোন ইউআইবাটন - চিত্রের অবস্থান


116

আমার কাছে UIButton"অ্যাপ্লিকেশনটি এক্সপ্লোর করুন" এবং UIImage(>) Interface Builderপাঠ্যযুক্ত রয়েছে যা দেখে মনে হচ্ছে:

[ (>) Explore the app ]

তবে UIImageলেখার পরে আমার এটি স্থাপন করা দরকার :

[ Explore the app (>) ]

আমি কীভাবে UIImageডানে সরাতে পারি ?


আপনি ইন্টারফেস বিল্ডারও ব্যবহার করতে পারেন। : এখানে আমার উত্তর চেক আউট stackoverflow.com/questions/2765024/...
n8tr

1
কয়েকটি সারি কোড সহ এই উপক্লাসটি
k06a

উত্তর:


161

এটির জন্য আমার সমাধানটি বেশ সহজ

[button sizeToFit];
button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width);

4
এটি দুর্দান্ত কাজ করে! প্রান্ত ইনসেট ধারণাটি বোঝা শক্ত। কোনও ধারণা কেন আমাদের বাম এবং ডান প্রান্তের ইনসেটটি সেট করতে হবে? তাত্ত্বিকভাবে, আমি শিরোনাম বাম দিকে এবং চিত্রটি ডানে সরিয়ে দিলে এটি যথেষ্ট be আমাকে কেন বাম এবং ডান উভয় সেট করতে হবে?
পোকারআইনকম.কম

3
সেরা সমাধান আমি খুঁজে পেয়েছি
বিমাওয়া

2
এই উত্তর নিখুঁতভাবে কাজ করে। গৃহীত উত্তরটি সঠিক, এবং সঠিক এপিআই ডক্সকে নির্দেশ করে, তবে এটি ওপি অনুরোধ করে যা করার জন্য অনুলিপি এবং পেস্ট সমাধান।
mclaughlinj

আপনি বোতামের পাঠ্য পরিবর্তন করা শুরু করার সময় কিছুটা জটিল হয়ে ওঠে। এই ক্ষেত্রে সাবক্ল্যাসড সমাধানটি আমার পক্ষে আরও ভাল কাজ করেছে।
ব্র্যাড গস

আপনাকে বাম এবং ডানদিকে সমান প্রস্থ প্রয়োগ করতে হবে আমাকে দেখানোর জন্য আপনাকে ধন্যবাদ, আমি এটি 100% বুঝতে পারি না এটি কীভাবে কাজ করে (কারণ কখনও কখনও এটি আকারের পাশাপাশি উত্সকেও প্রভাবিত করবে) তবে আমি অনুরূপ সমস্যাগুলি সমাধান করতে সক্ষম হয়েছি এই পদ্ধতি ব্যবহার করে।
টবি

128

উপর iOS 9 এর অগ্রে, মনে হচ্ছে যে এই অর্জন এটি একটি সহজ উপায় দৃশ্য শব্দার্থিক বাধ্য হয়।

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

বা প্রোগ্রামগতভাবে:

button.semanticContentAttribute = .ForceRightToLeft

4
আমি আপনার উত্তরটি যতটা পছন্দ করেছি (+1), এটি করার পক্ষে এটি "যথাযথ" উপায় নাও হতে পারে বলে আমি ঘৃণা করি তবে এটি অন্যতম সহজতম উপায়।
farzadshbfn

আপনি ঠিক বলেছেন ঠিক আছে আমি "সরল" শব্দটির জন্য পরিবর্তন করেছি, আরও ধারাবাহিক বলে মনে হচ্ছে।
আলভিভি

@ ফারজাদশবিফএন কেন এটি "যথাযথ" উপায় হবে না?
সম্মান বিক্রম থাপা

3
@ সাম্মানবিক্রম থাপ আইএমএইচও সঠিক উপায় হ'ল ইউআইবাটনটি সাবক্লাস করা এবং লেআউটের উপর নজর রাখা ও পর্যালোচনা করা semanticContentAttributeএবং আমাদের বিন্যাসের যুক্তিতে সম্মান প্রদর্শন করা , পরিবর্তে পরিবর্তিত হওয়া semanticContentAttribute। (শব্দার্থক পদ্ধতির পরিবর্তন, আন্তর্জাতিকীকরণের সাথে ভাল কাজ করবে না)
farzadshbfn

@ ফারজাদশবিফএন সম্পূর্ণরূপে ঠিক আছে। এই উত্তরটি বেশিরভাগ পয়েন্ট স্কোর করে তা সঠিক নয় - এটি ডান থেকে বাম ইন্টারফেসের জন্য ইউএক্সকে ভেঙে দিতে পারে।
পাভেল ইয়াকিমেনকো

86

আপনার চিত্রের মধ্যে উপাদানগুলি চারদিকে সরানোর জন্য imageEdgeInsetএবং সেট করুন titleEdgeInset। আপনি পূর্ণ আকারের সেই গ্রাফিকগুলি ব্যবহার করে একটি বোতামও তৈরি করতে পারেন এবং বোতামটির ব্যাকগ্রাউন্ড চিত্র হিসাবে ব্যবহার titleEdgeInsetsকরতে পারেন (তারপরে শিরোনামটি চারদিকে সরানোর জন্য ব্যবহার করুন )।


8
একটি সাবক্লাস বাস্তবায়নের চেয়ে কেবল ইনসেটগুলি সেট করা অনেক কম কোড। এই পোকার পুরো পয়েন্ট। সাব ভিউগুলির জন্য ফ্রেমগুলি পরিচালনা করে (যা আপনি তৈরি করেননি) হ্যাকের মতো মনে হয়।
কিম আন্দ্রে স্যান্ড

6
@ কিসমসনার্ফ, সত্যি? আপনি যখনই ইমেজের আকার বা শিরোনামের দৈর্ঘ্যের ক্ষেত্রে সামান্য পরিবর্তন করেন তখন কীটপতঙ্গগুলি টুইঙ্ক করা অনেক কম কাজ (এবং একটি হ্যাক কম )?
কર્ક ভোল

54

রেমন্ড ডাব্লু এর উত্তর এখানে সেরা। কাস্টম লেআউটসুভিউগুলি সহ সাবক্লাস ইউআইবাটন। এটি করা অত্যন্ত সহজ, এখানে একটি লেআউটসুবিউ বাস্তবায়ন যা আমার পক্ষে কাজ করেছে:

- (void)layoutSubviews
{
    // Allow default layout, then adjust image and label positions
    [super layoutSubviews];

    UIImageView *imageView = [self imageView];
    UILabel *label = [self titleLabel];

    CGRect imageFrame = imageView.frame;
    CGRect labelFrame = label.frame;

    labelFrame.origin.x = imageFrame.origin.x;
    imageFrame.origin.x = labelFrame.origin.x + CGRectGetWidth(labelFrame);

    imageView.frame = imageFrame;
    label.frame = labelFrame;
}

2
আপনার অনেকগুলি বোতাম পরিচালনা করার ক্ষেত্রে এই
পদ্ধতিটি আরও ভাল

2
যদি বোতামের চিত্রটি শূন্য থাকে তবে লেবেলের ফলাফলগুলি ভুল জায়গায় স্থান পেয়েছে, সম্ভবত ইউআইআইমেজভিউ প্রবেশ করা হয়নি (iOS6.0 তে পরীক্ষিত)। আপনার যদি কেবল চিত্রভিউ.ইমেজটি শূন্য না হয় তবে ফ্রেমগুলির সম্পাদনা বিবেচনা করা উচিত।
স্কাক্কো

2
আমি এই উত্তরের জন্য নিম্নোক্ত উন্নতির পরামর্শ দেব যাতে উভয় মতামতই কেন্দ্রীভূত থাকে: 'সিজিফ্লোট ক্রমবর্ধমানভিদথ = সিজিআরেক্টগেটউইথ (চিত্রফ্রেম) + সিজিআরেক্টগেটউইথ (লেবেল ফ্রেম) + 10; সিজিফ্লোট অত্যধিকউইডথ = সিজিআরেক্টগেটউইথ (স্ব.বাউন্ডস) - ক্রমবর্ধমান; labelFrame.origin.x = অতিরিক্তউইথ / 2; imageFrame.origin.x = CGRectGetMaxX (লেবেল ফ্রেম) + 10; '
আই-কনভ

এটি আমার জন্য আইওএস 7 এ বিরতি দেয়। অন্য কেউ? 8. iOS এ কাজ করে জরিমানা
rounak

1
IOS7 সমর্থন করবেন না এবং আপনার সমস্যাটি চলে যাবে। আপনার যাহাই হউক না কেন।
গিল

30

সাবক্লাসিং UIButtonএবং ওভাররাইডিং সম্পর্কে কী layoutSubviews?

তারপরে self.imageView& এর অবস্থানগুলি পোস্ট-প্রসেসিং করুনself.titleLabel


4
হ্যান্ড-টিউন করা ইনসেটগুলি ব্যবহার করে সবকিছু সঠিকভাবে স্থাপন করার চেষ্টা করার বিষয়ে এটি অন্য সমস্ত পরামর্শের (উপরের মত) এর চেয়ে অনেক সহজ।
স্টিভেন ক্র্যামার

13

আর একটি সহজ উপায় (এটি কেবল আইওএস 9 নয়) এই দুটি পদ্ধতির ওভাররাইড করার জন্য ইউআইবাটন সাবক্লাস করা

override func titleRectForContentRect(contentRect: CGRect) -> CGRect {
    var rect = super.titleRectForContentRect(contentRect)
    rect.origin.x = 0
    return rect
}

override func imageRectForContentRect(contentRect: CGRect) -> CGRect {
    var rect = super.imageRectForContentRect(contentRect)
    rect.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(rect)
    return rect
}

contentEdgeInsets ইতিমধ্যে সুপার ব্যবহার করে অ্যাকাউন্টে নেওয়া হয়।


ধন্যবাদ! সাবক্লাস এবং ওভাররাইড লেআউটসুবউভিউস () :) এর উত্তরগুলির চেয়ে আমি এটির চেয়ে অনেক বেশি পছন্দ করি
জো সুসনিক

1
আমার নম্র মতামত এ সম্পর্কে ভাল উপায় :)
DrPatience

9

আপনার অ্যাপ্লিকেশন যদি 'বাম থেকে ডান' এবং 'ডান থেকে বাম' উভয় সমর্থন করে তবে বোতামটির জন্য 'ডান থেকে বাম' জোর করা কোনও বিকল্প নয়।

আমার জন্য যে সমাধানটি কাজ করেছিল তা হ'ল একটি সাবক্লাস যা স্টোরিবোর্ডের বোতামে যুক্ত হতে পারে এবং সীমাবদ্ধতার সাথে ভালভাবে কাজ করে (আইওএস 11 এ পরীক্ষিত):

class ButtonWithImageAtEnd: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let imageView = imageView, let titleLabel = titleLabel {
            let padding: CGFloat = 15
            imageEdgeInsets = UIEdgeInsets(top: 5, left: titleLabel.frame.size.width+padding, bottom: 5, right: -titleLabel.frame.size.width-padding)
            titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageView.frame.width, bottom: 0, right: imageView.frame.width)
        }

    }

}

যেখানে 'প্যাডিং' শিরোনাম এবং চিত্রের মধ্যে স্থান হবে।


অবশ্যই .forceRightToLeftএকটি বিকল্প! শুধু বিপরীত মান (ব্যবহার .forceLeftToRightকরে থাকেন) UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft
মনমাল

5

সুইফটে:

override func layoutSubviews(){
    super.layoutSubviews()

    let inset: CGFloat = 5

    if var imageFrame = self.imageView?.frame,
       var labelFrame = self.titleLabel?.frame {

       let cumulativeWidth = imageFrame.width + labelFrame.width + inset
       let excessiveWidth = self.bounds.width - cumulativeWidth
       labelFrame.origin.x = excessiveWidth / 2
       imageFrame.origin.x = labelFrame.origin.x + labelFrame.width + inset

       self.imageView?.frame = imageFrame
       self.titleLabel?.frame = labelFrame  
    }
}

4

@ স্প্লিট দ্বারা উত্তরটি তৈরি করা ...

উত্তরটি চমত্কার, তবে এটি এড়িয়ে যায় যে বোতামটিতে কাস্টম চিত্র এবং শিরোনাম প্রান্তের ইনসেট থাকতে পারে যা আগে থেকেই সেট করা আছে (যেমন স্টোরিবোর্ডে)।

উদাহরণস্বরূপ, আপনি ইমেজটির পাত্রে উপরের এবং নীচের দিক থেকে কিছু প্যাডিং রাখতে চাইতে পারেন, তবে চিত্রটি বোতামের ডানদিকে সরাতে পারেন।

আমি এই পদ্ধতিটি দিয়ে ধারণাটি প্রসারিত করেছি: -

- (void) moveImageToRightSide {
    [self sizeToFit];

    CGFloat titleWidth = self.titleLabel.frame.size.width;
    CGFloat imageWidth = self.imageView.frame.size.width;
    CGFloat gapWidth = self.frame.size.width - titleWidth - imageWidth;
    self.titleEdgeInsets = UIEdgeInsetsMake(self.titleEdgeInsets.top,
                                            -imageWidth + self.titleEdgeInsets.left,
                                            self.titleEdgeInsets.bottom,
                                            imageWidth - self.titleEdgeInsets.right);

    self.imageEdgeInsets = UIEdgeInsetsMake(self.imageEdgeInsets.top,
                                            titleWidth + self.imageEdgeInsets.left + gapWidth,
                                            self.imageEdgeInsets.bottom,
                                            -titleWidth + self.imageEdgeInsets.right - gapWidth);
}

2
// Get the size of the text and image
CGSize buttonLabelSize = [[self.button titleForState:UIControlStateNormal] sizeWithFont:self.button.titleLabel.font];
CGSize buttonImageSize = [[self.button imageForState:UIControlStateNormal] size];

// You can do this line in the xib too:
self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;

// Adjust Edge Insets according to the above measurement. The +2 adds a little space 
self.button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, -(buttonLabelSize.width+2));
self.button.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, buttonImageSize.width+2);

এটি ডান-সংযুক্ত বোতাম তৈরি করে, এর মতো:

[           button label (>)]

প্রসঙ্গ অনুসারে বোতামটি এর প্রস্থটি সামঞ্জস্য করে না, তাই লেবেলের বামদিকে স্থান উপস্থিত হবে। আপনি এটি বাটন লেবেলসাইজ.উইথ এবং উইন্ডো আইজেমসাইজ.উইথ থেকে বোতামের ফ্রেমের প্রস্থ গণনা করে সমাধান করতে পারেন।



0

এই সমাধানটি আইওএস 7 এবং ততোধিক কাজ করে

জাস্ট সাবক্লাস ইউআইবাটন ton

@interface UIButton (Image)

- (void)swapTextWithImage;

@end

@implementation UIButton (Image)

- (void)swapTextWithImage {
   const CGFloat kDefaultPadding = 6.0f;
   CGSize buttonSize = [self.titleLabel.text sizeWithAttributes:@{
                                                               NSFontAttributeName:self.titleLabel.font
                                                               }];

   self.titleEdgeInsets = UIEdgeInsetsMake(0, -self.imageView.frame.size.width, 0, self.imageView.frame.size.width);
   self.imageEdgeInsets = UIEdgeInsetsMake(0, buttonSize.width + kDefaultPadding, 0, -buttonSize.width); 
}

@end

ব্যবহার (আপনার শ্রেণি কোথাও):

[self.myButton setTitle:@"Any text" forState:UIControlStateNormal];
[self.myButton swapTextWithImage];

0

পূর্ববর্তী উত্তর উপর বিল্ডিং। আপনি যদি আইকন এবং বোতামের শিরোনামের মধ্যে একটি মার্জিন রাখতে চান, তবে অভ্যন্তরীণ আকারের বোতামগুলির সীমার উপরে লেবেল এবং আইকনটি ভাসমান রোধ করতে কোডকে কিছুটা পরিবর্তন করতে হবে।

let margin = CGFloat(4.0)
button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width)
button.contentEdgeInsets = UIEdgeInsetsMake(0, margin, 0, margin)

শেষ কোড লাইনটি স্বয়ংক্রিয় বিন্যাসের জন্য অভ্যন্তরীণভাবে সামগ্রীর আকারের গণনার জন্য গুরুত্বপূর্ণ।


0

জিনিসটি করার জন্য এখানে আমার নিজস্ব উপায়, (প্রায় 10 বছর পরে)

  1. UIButton (বোতাম, যেমন আমরা সুইফট যুগে বাস করছি) এর সাবক্লাস
  2. স্ট্যাক ভিউতে একটি চিত্র এবং একটি লেবেল রাখুন।
class CustomButton: Button {

    var didLayout: Bool = false // The code must be called only once

    override func layoutSubviews() {
        super.layoutSubviews()
        if !didLayout, let imageView = imageView, let titleLabel = titleLabel {
            didLayout = true
            let stack = UIStackView(arrangedSubviews: [titleLabel, imageView])
            addSubview(stack)
            stack.edgesToSuperview() // I use TinyConstraints library. You could handle the constraints directly
            stack.axis = .horizontal
        }
    }
}

0

সুইফটে একক লাইন সমাধান:

// iOS 9 and Onwards
button.semanticContentAttribute = .forceRightToLeft

এটি ভাল নয় কারণ এটি সমস্ত আরটিএল ব্যবহারকারীদের জন্য বিন্যাসটি ভেঙে দেবে। তাদের জন্য আপনাকে বাম থেকে ডানদিকে জোর করতে হবে। আপনি আরও ভাল সমাধান এখান থেকে চেষ্টা করুন।
পাভেল ইয়াকিমেনকো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.