2011-07-26 7 views
33

Tôi không thể thay đổi văn bản UILabel. Mã cho các UILabel bên viewDidLoad là:Văn bản nhãn không được cập nhật

startLabel=[[UILabel alloc] initWithFrame:CGRectMake(75, 395, 200, 30)]; 
[email protected]"Recording Sound ..."; 
startLabel.backgroundColor=[UIColor clearColor]; 
startLabel.textColor=[UIColor whiteColor]; 
startLabel.font=[UIFont boldSystemFontOfSize:17]; 

[self.view addSubview:startLabel]; 

Sau đó, nếu tôi muốn thay đổi nhãn của văn bản với đoạn mã sau, nó không thay đổi trên ứng dụng:

[email protected]"Searching Database ..."; 

hoặc

[startLabel setText:@"Searching Database ..."]; 

Các UILabel là không có sản phẩm nào, tôi in nó ra trong gỡ lỗi và nó cho thấy:

(gdb) po startLabel 
<UILabel: 0x2c1a30; frame = (75 395; 200 30); text = 'Searching Database ...'; 
clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x2ae8f0>> 

Vì vậy, văn bản của nhãn thay đổi bên trong UILabel, nhưng nó không được cập nhật trên màn hình.

Có ai vui lòng cho tôi biết Tôi bị thiếu ở đây không? Cảm ơn.

Chỉnh sửa 1: Tôi đã thử performSelectorOnMainThread: - không hoạt động đối với tôi. Chỉnh sửa 2: Tôi đang sử dụng các lớp AVFoundationASIHTTP để ghi lại âm thanh và tải tệp đã ghi lên đây. Không có gì khác. Không sử dụng bất kỳ chủ đề nào.

+0

Bạn đang cập nhật văn bản (phương pháp nào)? Nó cần phải trên cùng một luồng (xem: http://stackoverflow.com/questions/6000741/cant-redraw-uilabel-after-updating-text). –

+0

@Ben: aint cho monotouch? Ngoài ra, tôi ở trong cùng một chủ đề, chỉ là một chức năng khác! – Ahsan

+0

Tôi hoàn toàn bỏ lỡ rằng là một câu hỏi MonoTouch, nhưng tôi thấy một vấn đề tương tự về việc cần phải được trên cùng một thread trong một diễn đàn Mac sử dụng performSelectorOnMainThread (http://forums.macrumors.com/showthread.php?t=463200) , vì vậy tôi chỉ tự hỏi bạn đang gọi nó từ đâu. –

Trả lời

47

Bạn có thể đang gặp sự cố với luồng như được đề cập trong các nhận xét ở trên. Nếu bạn có một phương thức chạy trên luồng chính và thực hiện một số hoạt động (chẳng hạn như tìm kiếm cơ sở dữ liệu), các cập nhật mà bạn thực hiện cho giao diện người dùng sẽ không được cam kết cho đến khi vòng lặp chạy được kiểm soát. Vì vậy, nếu bạn có một thời gian, nhiệm vụ dài xảy ra trên các chủ đề chính, chạy mã này sau khi cài đặt nội dung của label:

- (void)doSomethingTimeConsuming 
    ... consume some time ... 
    ... set text of label ... 
    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]]; 
    ... continue long operation ... 
} 

này nên tuôn ra bất kỳ thay đổi giao diện người dùng mà bạn đã thực hiện. Mặc dù điều này có thể là một hack hợp lý và chức năng, nó không đánh bại sự thay thế. Tôi khuyên bạn nên thực hiện các tác vụ tốn thời gian của ứng dụng của mình trên một chuỗi nền và cập nhật giao diện người dùng thông qua chuỗi chính bằng cách sử dụng performSelectorOnMainThread:withObject:waitUntilDone:. Xem trang của Apple trên iOS Thread Management.

+0

Cảm ơn bạn đã đề xuất Đây là những gì tôi đang làm trong ứng dụng/chế độ xem. Tôi đang sử dụng AVFoundation để ghi lại một số âm thanh và sử dụng lớp ASIHTTP để tải lên không có gì đặc biệt .... Trong chức năng tải lên các tập tin (một chức năng tùy chỉnh), ban đầu tôi đang viết mã để thay đổi nhãn hiệu.Không có gì hoạt động.Tôi thậm chí đã cố gắng performSelectorOnMainThread ... didnt làm việc.Bạn có nghĩ rằng ghi âm/tải lên đủ điều kiện như là một chủ đề riêng biệt? Xin vui lòng đề nghị những gì tôi có thể làm.Thêm – Ahsan

+0

âm thanh giống như tải lên của bạn trên chủ đề chính – bshirley

+1

[[NSRunLoop mainRunLoop] .. thingy làm việc .... thay thế khác didnt ... cảm ơn một bó .. :) bạn chỉ cần thực hiện ngày của tôi! – Ahsan

48

Trong trường hợp của tôi, hàm đang cập nhật được gọi từ trình nhận dạng cảm ứng trên một chuỗi, nhưng vị trí trong hàm tôi đang thay đổi giá trị của thuộc tính văn bản của nhãn tôi đặt nó trở lại chủ đề chính:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.someLabel setText:someString]; 
}); 
+0

Đơn giản và dễ dàng. Cảm ơn bạn! –

+0

Tôi đã cố gắng làm mới văn bản từ một phương thức được gọi trong trung tâm thông báo và điều này giải quyết được vấn đề, cảm ơn! – fray88

2

Tôi có một nhãn UIL hiển thị số cấp sẽ không cập nhật lên số cấp mới trên UIViewController. Các giải pháp khả thi duy nhất tôi có thể thấy rằng làm việc là để gọi setNeedsDisplay về các chủ đề chính của bộ điều khiển điểm cho rằng sở hữu UILabel

-(void)changeLevelLabel:(int)theLevel { 
dispatch_async(dispatch_get_main_queue(), ^{ 
    self.levelLabel.text = [NSString stringWithFormat:@"%d",theLevel]; 
    [self.levelLabel setNeedsDisplay]; 
}); 

}

Xem http://iosdevelopmentjournal.com/blog/2013/01/16/forcing-things-to-run-on-the-main-thread/ cho một lời giải thích chi tiết hơn

3

Mine của một chút bất ngờ hơn, mặc dù hợp lý - không phải là một cái gì đó bất cứ ai nghĩ quá khó.

Tôi phải cập nhật UILabel khi tôi nhận được NSNotification mà tôi đã kích hoạt ở một nơi khác. Tuy nhiên, thông báo được kích hoạt từ chủ đề nền vì vậy ngay cả các phương pháp nghe cập nhật văn bản của nhãn cũng được kích hoạt trong nền.

Nếu bạn đang dựa vào một số NSNotification để cập nhật nhãn hoặc bất kỳ chế độ xem nào của bạn, hãy kích hoạt NSNotification từ chuỗi giao diện người dùng chính.