Форум программистов, компьютерный форум, киберфорум
Наши страницы
Objective-C
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.80
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
#1

Как правильно вызвать -(void)setNeedsDisplay? - Objective-C

03.01.2013, 22:43. Просмотров 2874. Ответов 14
Метки нет (Все метки)

Здравствуйте, форумчане. Собственно начал изучать сей язык. Решил написать программку, которая рисует график функции по некоторому параметру. При этом отрисовка идет в классе Graph: UIView (он присвоен отдельной вьюшке)внутри метода drawRect. При этом в контроллере ViewController у меня текстовое поле для ввода и кнопка для передачи параметра в класс Graph.
Как мне обновить мой график при нажатии на кнопку?

Objective-C
1
2
3
4
5
- (IBAction)bSend:(id)sender {
    int input = [tfield.text intValue]; //Получаю с текстового поля и перевожу в int
    [Graph getInputValue:(int)input]; //Отправляю в класс graph
    //Хотелось бы здесь сразу вызвать setNeedsDisplay
}


Но только я выношу [self setNeedsDisplay] вне метода drawRect, как компилятор начинает ругаться. ((
http://www.cyberforum.ru/ios-dev/thread1247042.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.01.2013, 22:43
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Как правильно вызвать -(void)setNeedsDisplay? (Objective-C):

Как вызвать функцию другого окна
Как вызвать функцию одного ВьюКонтроллера, в другом ВьюКонтроллере? Вопрос...

Как правильно заполнить массив из указателей типа void*
Насколько я понимаю, его можно заполнить, только присваивая адреса элементам...

Internal Void? как правильно аргумент преобразовать в int
using System; using ConsoleApp2; using ConsoleApp2.Fifo; using System;...

Вызвать функцию возвращающую void
Замечал, что можно VOID использовать отдельно от main function, при надобности...

как правильно вызвать sub?
Назрело несколько ворпросов об использовании sub'ов 1)как правильно вызвать...

14
zulkis
684 / 611 / 43
Регистрация: 13.01.2011
Сообщений: 1,724
04.01.2013, 10:55 #2
Цитата Сообщение от IhorMihal Посмотреть сообщение
[Graph getInputValueint)input]; //Отправляю в класс graph
Если getSomething - то по идее он должен быть без аргумента, и метод должен возвращать что либо(геттер).

Цитата Сообщение от IhorMihal Посмотреть сообщение
Но только я выношу [self setNeedsDisplay] вне метода drawRect, как компилятор начинает ругаться. ((
А self у Вас какого типа?
Вероятно UIViewController. А Вам нужно перерисовать Ваш Graph. Ну вот его экземпляру и посылайте setNeedsDisplay.
1
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
04.01.2013, 21:39  [ТС] #3
Цитата Сообщение от IhorMihal Посмотреть сообщение
[Graph getInputValueint)input]; //Отправляю в класс graph
Не обращайте внимание на название - параметр передается хорошо - проверено. Проблема сделать обновление при нажатии кнопки bSend, которое вызывает метод displayUpdate

Признаю, пока для меня все это туго...
Вот мой класс Graph.m:

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#import "Graph.h"
 
@implementation Graph
int tvalue=1; //Значение по умолчанию
+(void)getInputValue:(int) temp {    //Получаем значение
    tvalue=temp;
}
+(int)sendInputValue {  //При вызове мотод отправляет значение обратно для вывода на экран (для проверки)
    return tvalue;
}
 - (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
    }
    return self;
}
 - (void)drawRect:(CGRect)rect
{
 CGContextRef context = UIGraphicsGetCurrentContext();
 CGContextClearRect(context, rect); 
 CGContextSetRGBStrokeColor (context, 255, 255, 255, 1);
 int y;
 for (int x=rect.origin.x; x<rect.size.width; x++)
 {   
 y = x*tvalue;     //Собственно пример моей функции
     if (x==0) CGContextMoveToPoint (context, x, y);
 else CGContextAddLineToPoint (context, x, y);
 }
 CGContextStrokePath (context);
    [self setNeedsDisplay];     // Здесь компилятору все нравится, но нет возможности обновления при нажатии на кнопку
}
/* +(void) displayUpdate {
 [self setNeedsDisplay];       //Здесь компилятор выдает: No known class method for selector 'setneedsdisplay'
} */
@end
0
zulkis
684 / 611 / 43
Регистрация: 13.01.2011
Сообщений: 1,724
06.01.2013, 19:43 #4
Цитата Сообщение от IhorMihal Посмотреть сообщение
Не обращайте внимание на название - параметр передается хорошо - проверено
При чем тут "не обращайте внимание". У Вас написано семантически неверно - вот и все внимание.
Насчет кода: CTRL+I спасет положение. Форматирования нет совсем, что не есть хорошо.

Цитата Сообщение от IhorMihal Посмотреть сообщение
[self setNeedsDisplay];
в drawRect - это очень плохо. Это неверно в корне. Прочитайте для чего нужен данный метод в документации.


Цитата Сообщение от IhorMihal Посмотреть сообщение
+(void) displayUpdate {
*[self setNeedsDisplay]; * * * //Здесь компилятор выдает: No known class method for selector 'setneedsdisplay'
}
Вы написали статический метод. И посылается сообщение классу с итоге, а не экземпляру.
Напишите
Objective-C
1
2
3
- (void)displayUpdate {
    [self setNeedsDisplay]; 
}
и вызывайте его у экземпляра класса.
А лучше уберите этот ненужный метод и вызывайте
Objective-C
1
[_yourGraphView setNeedsDisplay];
1
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
07.01.2013, 17:25  [ТС] #5
Объявил экземпляр класса Graph. Ошибок в коде теперь нет. Но мой View не обновляется при вызове [myGraph setNeedsDisplay]. Может проблема в инициализации экземпляра myGraph класса Graph?

в ViewController.m:

Objective-C
1
2
3
4
5
6
- (IBAction)bSend:(id)sender {
    int input = [inputvalue.text intValue];
    MyCanvas* myGraph = [[MyCanvas alloc] init];
    [myGraph setParametr:(int) input];
    [myGraph setNeedsDisplay];
}
В Graph.h и Graph.m тоже нужно объявлять экземпляр myGraph?
И еще не совсем понятно (документацию прочел) назначение этого:
Objective-C
1
2
3
4
5
6
7
8
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
     //  Initialization code here
    }
    return self;
}
Что именно здесь нужно инициализировать? И нужно ли мне это делать в моем случае?
0
zulkis
684 / 611 / 43
Регистрация: 13.01.2011
Сообщений: 1,724
08.01.2013, 11:36 #6
Каждый раз не нужно создавать новую view(Ваш MyCanvas).
И если Вы создали view, её же нужно отобразить(читай добавить на "экран")
Используйте -addSubview: метод

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@interface ViewController() {
   MyCanvas *myGraph;
}
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
   [super viewDidLoad];
   myGraph = [[MyCanvas alloc] init];
   [self.view addSubview:myGraph];
}
 
- (IBAction)bSend:(id)sender {
    int input = [inputvalue.text intValue];
    [myGraph setParametr:(int) input];
    [myGraph setNeedsDisplay];
}
 
@end
Как то так.
0
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
09.01.2013, 04:18  [ТС] #7
Все равно вьюшка не обновляется . Надеялся, что ошибка в передаче параметра. Проверил всевозможными способами - мой график обновляется только при первой загрузке... [myGraph setNeedsDisplay] ничего не делает
0
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
10.01.2013, 21:12 #8
Я бы начал отладку с того, что поставил в drawRect: break point или NSLog и посмотрел вызывается ли этот метод после нажатия на кнопку, а заодно и значение tvalue. Уж больно оно хитро меняется - через метод класса, а не экземпляра. Это точно так надо или Вы просто разницы между ними не видите?
0
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
10.01.2013, 22:48  [ТС] #9
У меня все методы теперь от экземпляра. Выполнения drawRect по нажатии на кнопку не происходит. Только при запуске....
0
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
10.01.2013, 22:53 #10
Последний вариант кода можно увидеть? И не только реализацию, но и заголовок этого класса.
0
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
11.01.2013, 03:14  [ТС] #11
Цитата Сообщение от mobidevelop Посмотреть сообщение
Последний вариант кода можно увидеть? И не только реализацию, но и заголовок этого класса.
ViewController.h:
Objective-C
1
2
3
4
5
6
7
8
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
    {
        IBOutlet UITextField *inputvalue;
        IBOutlet UILabel *outputvalue;
    }
- (IBAction)sendInputvalue:(id)sender;
@end
ViewController.m:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#import "ViewController.h"
#import "MyCanvas.h"
 
@interface ViewController () {
 MyCanvas* myGraph;
}
@end
 
@implementation ViewController
 
int input;
- (void)viewDidLoad
{
    [super viewDidLoad];
    myGraph = [[MyCanvas alloc] init];
    [self.view addSubview:myGraph];    
}
 
- (IBAction)sendInputvalue:(id)sender {
    input = [inputvalue.text intValue];
    [myGraph setParametr:(int) input];
    [myGraph setNeedsDisplay];
    int output = [myGraph getParametr];
    outputvalue.text = [NSString stringWithFormat:@"%d",output];
}
 
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
    inputvalue = nil;
    outputvalue = nil;
    [super viewDidUnload];
}
@end
MyCanvas.h:
Objective-C
1
2
3
4
5
6
7
#import <UIKit/UIKit.h>
 
@interface MyCanvas : UIView
 
- (void) setParametr:(int)input;
- (int) getParametr;
@end
MyCanvas.m:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#import "MyCanvas.h"
 
@implementation MyCanvas
 
int parametr=0;
 
-(void) setParametr:(int)input {
    parametr=input;
}
 
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {       
    }
    return self;
}
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    
    CGContextSetRGBStrokeColor (context, 255, 255, 255, 1);
    int y;
    for (int x=rect.origin.x; x<rect.size.width; x++)
    {
        y = x*parametr;
        if (x==0) CGContextMoveToPoint (context, x, y);
        else CGContextAddLineToPoint (context, x, y);
    }
    CGContextStrokePath (context);
}
-(int) getParametr {
    return parametr;
}
@end
0
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
11.01.2013, 12:12 #12
1. ViewController.m, строка 15:
Objective-C
1
myGraph = [[MyCanvas alloc] initWithFrame:self.view.bounds];
2. MyCanvas.m, строка 25:
Objective-C
1
for (int x=rect.origin.x; x<rect.origin.x+rect.size.width; x++)
width - это не правая координата прямоугольника, а его ширина. Разница существенная, если левая координата не нулевая.
А в 23-й строке цвет задается белый. Поэтому саму вьюху лучше бы для уверенности в черный перекрасить. Сразу после создания вставить:
Objective-C
1
myGraph.backgroundColor = [UIColor blackColor];
Попробуйте - должно получиться.
0
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
11.01.2013, 18:40  [ТС] #13
Цитата Сообщение от mobidevelop Посмотреть сообщение
1. ViewController.m, строка 15:
Код Objective-C
Objective-C
1
myGraph = [[MyCanvas alloc] initWithFrame:self.view.bounds];
Теперь вью моего графика занимает весь экран... Как сделать такой же размер как и view в IB, которому назначен класс MyCanvas?
0
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
11.01.2013, 18:55 #14
А! Теперь проблема понятна. Ручное создание этой вьюхи вообще убрать надо. Надо создать в контроллере проперть с модификатором IBOutlet типа MyCanvas и прицепить к ней вью, созданную в IB.
Objective-C
1
@property (nonatomic, strong) IBOutlet MyCanvas* myGraph;
Тогда все начнет перерисовываться
1
IhorMihal
0 / 0 / 1
Регистрация: 03.01.2013
Сообщений: 9
11.01.2013, 19:39  [ТС] #15
Цитата Сообщение от mobidevelop Посмотреть сообщение
Objective-C
1
@property (nonatomic, strong) IBOutlet MyCanvas* myGraph;
Ааа! Вот это оно! К контроллеру забыл привязать! Не знаю, сколько еще сам бы думал. Спасибо!
0
11.01.2013, 19:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.01.2013, 19:39
Привет! Вот еще темы с решениями:

Как правильно вызвать JS
Здравствуйте. Есть код: &lt;a class=&quot;btn btn-success waves-effect waves-light&quot;...

Как правильно вызвать процедуру?
как правильно вызвать данную процедуру? procedure n1(i:integer; A:T1); begin...

Как правильно вызвать объект
Доброго времени суток, такое дело создаю свою функцию и из неё вызвать Label,...

Как правильно вызвать функцию?
Здравствуйте,посдкажите как правильно объявить функцию в private и вызвать ее в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru