কোনও ইউআইভিউ রাইজ আকারে ইভেন্ট আছে?


102

আমার কাছে একটি ভিউ রয়েছে যাতে এতে সারি এবং ইমেজভিউগুলির কলামগুলি থাকে।

যদি এই ভিউটির আকার পরিবর্তন করা হয়, তবে আমাকে চিত্রদর্শনগুলির অবস্থানগুলি পুনরায় সাজানো দরকার।

এই মতামতটি পুনরায় আকার দেয় এমন অন্য দর্শনের একটি সংক্ষিপ্তসার।

এই দৃষ্টিভঙ্গিটি যখন পুনরায় আকার দেওয়া হচ্ছে তখন কি সনাক্ত করার কোনও উপায় আছে?


ভিউ পুনরায় আকার দেওয়া হয়? ডিভাইসটি কখন ঘোরানো হয়, বা যখন ব্যবহারকারী এটি ঘুরিয়ে দেয় মাল্টি টাচ ব্যবহার করে?
ইভান মুলাওস্কি

ব্যবহারকারী যখন অন্য ভিউতে (মাস্টার ভিউ) বোতামে টিপবে তখন এই দৃশ্যটি পুনরায় আকার দেওয়া হয়।
লাইভ-লাভ

উত্তর:


98

উলি যেমন নীচে মন্তব্য করেছেন, এটি করার যথাযথ উপায় হ'ল ওভাররাইড layoutSubviewsএবং সেখানে চিত্রটি দেখুন layout

যদি কোনও কারণে আপনি সাবক্লাস এবং ওভাররাইড করতে না পারেন তবে layoutSubviewsপর্যবেক্ষণের boundsকাজ করা উচিত, এমনকি একধরণের নোংরা হওয়ার পরেও। আরও খারাপ, পর্যবেক্ষণের সাথে ঝুঁকি রয়েছে - অ্যাপল কেভিও ইউআইকিট ক্লাসে কাজ করার গ্যারান্টি দেয় না। অ্যাপল ইঞ্জিনিয়ারের সাথে আলোচনাটি এখানে পড়ুন: কোনও সম্পর্কিত বিষয় কখন প্রকাশিত হয়?

মূল উত্তর:

আপনি কী-মান পর্যবেক্ষণ ব্যবহার করতে পারেন:

[yourView addObserver:self forKeyPath:@"bounds" options:0 context:nil];

এবং বাস্তবায়ন:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (object == yourView && [keyPath isEqualToString:@"bounds"]) {
        // do your stuff, or better schedule to run later using performSelector:withObject:afterDuration:
    }
}

2
সত্যই, সংক্ষিপ্তসারগুলি পর্যালোচনাগুলি হ'ল লেআউটসুভিউগুলির জন্য ঠিক কী, তাই আকার পরিবর্তনগুলি পর্যবেক্ষণ করা হয়, কার্যকরী অবস্থায়, আইএমও বাজে নকশা।
uliwitness

@ প্রত্যক্ষদর্শী ভাল তারা এই জিনিস পরিবর্তন করতে না। যাই হোক, এখন আপনি ব্যবহার করা উচিত viewWillTransitionইত্যাদি ইত্যাদি
ড্যান Rosenstark

ইউআইভিউ কনট্রোলারদের জন্য ভিউল্ট ট্রান্সনিশনেশন, ইউআইভিউ নয়।
আরমান্ড

layoutSubviewsভিউটির বর্তমান আকারের উপর নির্ভর করে যদি আলাদা সাবভিউ যুক্ত করতে / মুছে ফেলার প্রয়োজন হয় এবং বিভিন্ন সীমাবদ্ধতা যুক্ত / মুছে ফেলা দরকার হয় তবে কি এখনও প্রস্তাবিত পদ্ধতি ব্যবহার করা হচ্ছে?
ক্রিস প্রিন্স

1
ঠিক আছে, আমি মনে করি আমি কেবল আমার মামলার জবাব দিয়েছি। আমি যখন সেটআপটি করি (আকারের উপর নির্ভরশীল) যখন আমার সীমানার ওভাররাইডে প্রয়োজন হয়, এটি কার্যকর হয়। আমি যখন এটি বিন্যাসে করি তবে পর্যালোচনাগুলি তা হয় না।
ক্রিস প্রিন্স

93

একটি UIViewসাবক্লাসে, সম্পত্তি পর্যবেক্ষকগুলি ব্যবহার করা যেতে পারে:

override var bounds: CGRect {
    didSet {
        // ...
    }
}

সাবক্ল্যাসিং ছাড়াই, স্মার্ট কী-পাথগুলির সাহায্যে কী-মান পর্যবেক্ষণটি করবে:

var boundsObservation: NSKeyValueObservation?

func beginObservingBounds() {
    boundsObservation = observe(\.bounds) { capturedSelf, _ in
        // ...
    }
}

2
@ অলি আপনি কেন এমন ভাবছেন?
রুডল্ফ অ্যাডমকোভিč

লোড ফ্রেমের পরিবর্তন ঘটে তবে এটি দেখতে সীমানার মতো লাগে না (আমি জানি এটি অদ্ভুত এবং সম্ভবত আমি কিছু ভুল করছি)
আলী

3
@ অলি: যেমনটি এখানে বেশ কয়েকবার উল্লেখ করা হয়েছে: frameএটি একটি উত্পন্ন এবং রানটাইম গণনা করা সম্পত্তি। যদি আপনার কাছে খুব স্মার্ট এবং বুদ্ধিমান কারণ না থাকে তবে এটিকে ওভাররাইড করবেন না। অন্যথায়: ব্যবহার boundsবা (আরও ভাল) layoutSubviews
auco

3
একটি চেনাশোনা তৈরি করার জন্য দুর্দান্ত উপায়। ধন্যবাদ! override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }}
সিম্পলজি

4
সনাক্তকরণ boundsবা frameপরিবর্তন কাজের গ্যারান্টিযুক্ত নয়, আপনি যেখানে ভিউ হায়ারার্কিতে আপনার দৃষ্টিভঙ্গি স্থাপন করেছেন তার উপর নির্ভর করে। আমি layoutSubviewsপরিবর্তে ওভাররাইড করব দেখুন এই এবং এই উত্তর।
হুয়াথাম

31

ইউআইভিউর সাবক্লাস তৈরি করুন এবং লেআউটসুভিউগুলি ওভাররাইড করুন


11
এর সাথে সমস্যা হ'ল সাবউভিউগুলি কেবল তাদের আকার পরিবর্তন করতে পারে না, তবে তারা আকার আকার পরিবর্তন করতে পারে। যখন ইউআইভিউভি অ্যানিমেশনটি চালায়, এটি প্রতিবার লেআউটসুভিউগুলিকে কল করে না।
ডেভিড জেস্ক

1
@ ডেভিডজেস্কে ইউআইভিউএনিমেশনঅপশনগুলিতে ইউআইভিউএনিমেশনঅপশনলয়আউটসুভিউস নামে একটি বিকল্প রয়েছে। আমি মনে করি এটি সম্ভবত সাহায্য করবে। :)
নিল.মার্লিন

8

সুইফট 4 কীপ্যাথ কেভিও - এইভাবে আমি স্বীকৃতি সনাক্ত করে এবং আইপ্যাডের সাইড প্যানেলে চলে আসছি। কাজ করা উচিত কোনও দৃষ্টিতে কাজ করা। ইউআইভিউয়ের স্তরটি পর্যবেক্ষণ করতে হয়েছিল।

private var observer: NSKeyValueObservation?

override func viewDidLoad() {
    super.viewDidLoad()
    observer = view.layer.observe(\.bounds) { object, _ in
        print(object.bounds)
    }
    // ...
}
override func viewWillDisappear(_ animated: Bool) {
    observer?.invalidate()
    //...
}

এই সমাধানটি আমার পক্ষে কাজ করেছিল। আমি সুইফটে নতুন এবং আপনি এখানে ব্যবহৃত b .সাগর সিনট্যাক্স সম্পর্কে আমি অনিশ্চিত। এর আসল অর্থ কি?
ডব্লুবুক


.layerকৌতুকটি করেছে! আপনি কি জানেন কেন ব্যবহার view.observeকরে কাজ হয় না?
d4Rk

@ d4Rk - আমি জানি না। আমার অনুমান যে স্তরটি ইউআইভিউ ফ্রেমের চেয়ে কম অস্পষ্ট। উদাহরণস্বরূপ, ইউআইটিএবলভিউয়ের সামগ্রীআফসেট তার উপভিউগুলির চূড়ান্ত স্থানাঙ্ককে প্রভাবিত করবে। নিশ্চিত না.
ওয়ারেন স্ট্রিংগার

এটি আমার জন্য একটি দুর্দান্ত উত্তর। আমার কেসটি হ'ল আমি আমার মতামত জানাতে অটলাউট ব্যবহার করছি। তবে ইউআইকিকলিশনভিউফ্লোএলআউট আপনাকে একটি স্পষ্ট আইটেম আকার দিতে বাধ্য করে। তবে যখন আপনার সংগ্রহ ভিউয়ের আকার পরিবর্তন হয় (যেমন আমি যখন অটোলআউট সহ একটি সরঞ্জামদণ্ড দেখাব তখন আমার মত) - আইটেম সাইজটি একই থাকে এবং ছুঁড়ে দেয় = [পর্যবেক্ষক আমার কাছে এ পর্যন্ত পাওয়া সবচেয়ে পরিষ্কার পদ্ধতির। এবং সেরা এক !!
যিটজাক

7

আপনি ইউআইভিউর একটি সাবক্লাস তৈরি করতে এবং ওভাররাইড করতে পারেন

setFrame: (CGRect) ফ্রেম

পদ্ধতি। যখন ভিউর ফ্রেম (অর্থাত্ আকার) পরিবর্তন করা হয় তখন এটিকে বলা হয়। এরকম কিছু করুন:

- (void) setFrame:(CGRect)frame
{
  // Call the parent class to move the view
  [super setFrame:frame];

  // Do your custom code here.
}

সংবেদনশীল এবং কার্যক্ষম। ভাল কল.
এল জোরকো

1
এফওয়াইআই এটি ইউআইএমেজভিউ সাবক্লাসের জন্য কাজ করে না। আরো এখানে তথ্য: stackoverflow.com/questions/19216684/...
উইলিয়াম Entriken

এছাড়াও, অটোোটোটেশনের কারণে পুনরায় আকার দেওয়ার সময় setFrame:আমার UITextViewসাবক্লাসে ডাকা layoutSubviews:হয়নি। দ্রষ্টব্য: আমি অটো লেআউট এবং আইওএস 7.0 ব্যবহার করছি।
ma11hew28

3
কখনই ওভাররাইড হবে না setFrame:frameএকটি উদ্ভূত সম্পত্তি। আমার উত্তর দেখুন
অ্যাডলাই হোলার

7

বেশ পুরানো তবে এখনও একটি ভাল প্রশ্ন। অ্যাপলের নমুনা কোডে এবং তাদের কয়েকটি ব্যক্তিগত ইউআইভিউউ সাবক্লাসে সেটবউন্ডগুলি মোটামুটিভাবে ওভাররাইড করে:

-(void)setBounds:(CGRect)newBounds {
    BOOL const isResize = !CGSizeEqualToSize(newBounds.size, self.bounds.size);
    if (isResize) [self prepareToResizeTo:newBounds.size]; // probably saves 
    [super setBounds:newBounds];
    if (isResize) [self recoverFromResizing];
}

ওভাররাইড setFrame:করা ভাল ধারণা নয়। frameথেকে উদ্ভূত হয়েছে center, boundsএবং transform, সুতরাং আইওএস অগত্যা কল করবে না setFrame:


2
এটি সত্য (তত্ত্ব অনুসারে)। যাইহোক, setBounds:ফ্রেম সম্পত্তি সেট করার সময় হয় না বলা হয় (কমপক্ষে আইওএস 7.1 এ)। এটি অতিরিক্ত বার্তা এড়াতে অ্যাপল যুক্ত একটি অপ্টিমাইজেশন হতে পারে।
nschum

1
… এবং অ্যাপল এর খারাপ নকশা তাদের নিজস্ব প্রবেশকারীদের কল না।
osxdirk

1
প্রকৃতপক্ষে এবং উভয়ই ভিউয়ের অন্তর্নিহিত থেকে উদ্ভূত ; তারা কেবল স্তরের প্রবেশকারীকে কল করে। এবং স্তর এর ফ্রেম সেট করে , যখন স্তর সীমা নির্ধারণ করে। সুতরাং আপনি কেবল একটি বা অন্যটিকে ওভাররাইড করতে পারবেন না। এছাড়াও, অতিরিক্তভাবে বলা হয় (কেবল জ্যামিতির পরিবর্তনের উপর নয়), তাই এটি সর্বদা ভাল বিকল্প নাও হতে পারে। এখনও খুঁজছি ...frameboundsCALayersetFrame:setBounds:layoutSubviews
বড়_২

-3

আপনি যদি কোনও ইউআইভিউউকন্ট্রোলার উদাহরণে viewDidLayoutSubviewsথাকেন তবে ওভাররাইড করা কৌশলটি করে does

override func viewDidLayoutSubviews() {
    // update subviews
}

ইউআইভিউ কন্ট্রোলার নয়, ইউআইভিউ আকার পরিবর্তন করা দরকার।
গ্যাস্তন আন্তোনিও মন্টেসে

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